
On Wed, Apr 02, 2008 at 04:26:04PM -0400, Patrick Surry wrote:
-- Why don't these (particularly g and g') all have the same type? Prelude> :t (\x -> x+1) (\x -> x+1) :: (Num a) => a -> a Prelude> let g = (\x -> x+1) Prelude> :t g g :: Integer -> Integer Prelude> let g' x = x + 1 Prelude> :t g' g' :: (Num a) => a -> a
It's the monomorphism restriction in action, along with defaulting. Basically, the rule is: Any binding of the form "g = ..." where there are no parameters *syntactically* must not be polymorphic with type-class restrictions. If you disable it with -fno-monomorphism-restriction then the differences go away. In addition, Haskell has some special-case "defaulting" rules for turning Num classed type-variables into concrete types, which explains the appearance of "Integer" specifically. The reason for existence of this restriction is that such a "g" may be recomputed for each use, much like a function call. This could lead to surprising behavior, though perfectly safe. In Haskell, it's not such a big deal, because of pure code, so some people prefer to turn the restriction off. Your options are to turn it off, always write syntactic parameters like "g x = ...", or provide an explicit polymorphic type signature like "g :: Num a => a -> a". -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org