Confused about typing in ghci
Matthew Danish
mdanish at andrew.cmu.edu
Wed Apr 2 16:40:03 EDT 2008
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
More information about the Glasgow-haskell-users
mailing list