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