
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) eg: f = \x -> x + 1 -- Integer -> Integer whereas 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 http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphismRestriction for the latest on what might happen to it in future versions of Haskell.) Brian. -- http://www.metamilk.com