[Haskell-cafe] MultiParamTypeClasses, FunctionalDependencies and FlexibleInstances using GHCi

Daniel Fischer daniel.is.fischer at web.de
Fri May 14 09:46:04 EDT 2010


On Friday 14 May 2010 15:32:10, Bulat Ziganshin wrote:
> Hello Julian,
>
> Friday, May 14, 2010, 4:18:42 PM, you wrote:
> > Now, if I type
> >
> >> 3 + 4
> >
> > it does not work, and i really don't understand why. If i ask GHCi
> > for 3's type ($ :t 3) it will answer "3 :: (Prelude.Num t) => t".
> > But, if 3 and 4 are Prelude.Nums and there is an instanfe Num x x x
> > for x of Prelude.Num - than why can't GHC deduce from the
> > definitions that 3 and 4, both Prelude.Nums, can be used with (+)
> > since there is an instance for Prelude.Num and my class Num - and
> > the result will of course be something of Prelude.Num?
>
> because 3 and 4 may have different types. Num is a class, Int is a
> concrete type. 3 without additional type signature is polymorphic
> value. usually type inference deduce types of numeric constants (that
> all are polymorphic) from context but in your case it's impossible
>
> your functional dependency allows to fix result type once parameter
> types are known, but not other way
>
> you appeal to *instance* definition but haskell/ghc type inference
> can't use instance heads to deduce types since classes are open and
> anyone can add later code that breaks your assumption (imagine that
> ghc generates code for your module and later this module is imported by
> someone else and additional instances are provided)

Exactly.


instance (Prelude.Num x) => Num x Prelude.Integer x where
    a + b = a Prelude.* Prelude.fromInteger b

*Main> 3 + (4 :: Prelude.Integer) :: Prelude.Double
12.0
*Main> 3 + (4 :: Prelude.Integer) :: Prelude.Integer

<interactive>:1:0:
    Overlapping instances for Num
                                Prelude.Integer Prelude.Integer 
Prelude.Integer
      arising from a use of `+' at <interactive>:1:0-25
    Matching instances:
      instance (Prelude.Num x) => Num x x x
        -- Defined at NClass.hs:7:9-36
      instance (Prelude.Num x) => Num x Prelude.Integer x
        -- Defined at NClass.hs:10:9-50
    In the expression: 3 + (4 :: Prelude.Integer) :: Prelude.Integer
    In the definition of `it':
        it = 3 + (4 :: Prelude.Integer) :: Prelude.Integer

>
> btw, quite popular problem, it arrives here each month or so :)
>
> there are some ghc pragmas that somewhat break this rule, you may try
> allow-indecidable-insances or so. but it's dangerous way



More information about the Haskell-Cafe mailing list