[Haskell-cafe] Strange type behavior in GHCi 6.4.2

Brian Hulley brianh at metamilk.com
Sat Dec 2 15:25:59 EST 2006

Grady Lemoine wrote:
>> f x = x^3
>> f' = snd . (evalDeriv f)
> When I load this in GHCi, I get:
> *Main> :t f
> f :: (Num a) => a -> a
> *Main> :t snd . (evalDeriv f)
> snd . (evalDeriv f) :: (Num a, Num (Dual a)) => a -> a
> *Main> :t f'
> f' :: Integer -> Integer
> Why is the type of f' Integer -> Integer, especially when the type of
> the expression it's defined as is more general?  Is this something I'm
> not understanding about Haskell, or is it more to do with GHC 6.4.2
> specifically?

This is the monomorphism restriction, which basically says that any binding 
which just has a single variable on the left of the '=' is artificially 
forced to be monomorphic (unless you've given it an explicit type signature) 

    f = \x -> x + 1        -- Integer -> Integer


    f x = x + 1        -- Num a => a -> a

The reason for this is that if you have something like:

    let x = e in (x,x)

you often expect the expression (e) to be evaluated at most once, and shared 
by the two components of the tuple. However if there were no monomorphism 
restriction, then (x) could be polymorphic hence (e) would have to be 
evaluated twice (once for each overloading, even if the result tuple is fed 
to another function which expects both elements to have the same type) which 
would make programs run slower than the programmer expected.

I couldn't find any page on the wiki about this, but there's lots of stuff 
scattered around on the web, and endless discussions in the Haskell mailing 
lists which make entertaining reading ;-)

(The MR is controversial - see 
for the latest on what might happen to it in future versions of Haskell.)


More information about the Haskell-Cafe mailing list