[Haskell-cafe] Re: RLE in Haskell: why does the type variable get instantiated?

apfelmus apfelmus at quantentunnel.de
Tue Jul 31 06:00:14 EDT 2007


Chris Eidhof wrote:
> When binding the function composition to a variable, the type
> suddenly changes.
> 
> Prelude Control.Arrow List> :t map (length &&& head) . group
> map (length &&& head) . group :: (Eq a) => [a] -> [(Int, a)]
> Prelude Control.Arrow List> let encode = map (length &&& head) . group
> Prelude Control.Arrow List> :t encode
> encode :: [Integer] -> [(Int, Integer)]

You've tripped over the Monomorphism Restriction.

  http://haskell.org/haskellwiki/Monomorphism_restriction
  http://haskell.org/onlinereport/decls.html#sect4.5.5

In short, you have to supply a type signature

  encode :: (Eq a) => [a] -> [(Int, a)]
  encode = map (length &&& head) . group

to get the polymorphic function type when type-classes like  Eq  or
especially  Num  are involved. Without signature, the compiler will
_default_ some the type variables mentioned in the class context to
Integer  or similar.

Note that definitions on the GHCi prompt will receive more defaulting
than those in Haskell source files. This is to make things like

  show []
  1+5

work at the prompt.

Also note that the monomorphism restriction only applies to constant
applicative forms, i.e. point-free definitions of values. In other words,

  encode x = map (length &&& head) . group $ x

will result in the proper polymorphic type.

Regards,
apfelmus



More information about the Haskell-Cafe mailing list