Reputation: 53
I wrote a function add'
in test.hs
:
add' = \x y -> x + y
Then I loaded test.hs
in GHCi (version 7.8.3), and typed :t add'
to watch what type add'
is. The result looks like incorrect:
*Main> :t add'
add' :: Integer -> Integer -> Integer
But if I typed :t (\x y -> x + y)
straightly in GHCi, the result is correct:
*Main> :t (\x y -> x + y)
(\x y -> x + y) :: Num a => a -> a -> a
Then I tried to rewrite the add'
in test.hs
as followed and :type
them in GHCi:
add1 = \x y -> x + y
add2 = \x -> \y -> x + y
add3 x y = x + y
The results are:
add1 :: Integer -> Integer -> Integer
add2 :: Integer -> Integer -> Integer
add3 :: Num a => a -> a -> a
But use let
clause to define a function and then :type
them or :type
the lambdas straightly in GHCi all results in type of Num a => a -> a -> a
Why are they different? Is it a bug of GHC?
Upvotes: 3
Views: 162
Reputation: 48634
You have hit upon the dreaded monomorphism restriction. Monomorphism restriction makes the type signature of your function specialized to a single type. You can turn off that using the extension NoMonomorphismRestriction
:
{-# LANGUAGE NoMonomorphismRestriction #-}
add1 = \x y -> x + y
add2 = \x -> \y -> x + y
add3 x y = x + y
And then when you load the types in ghci they will be:
λ> :t add1
add1 :: Num a => a -> a -> a
λ> :t add2
add2 :: Num a => a -> a -> a
λ> :t add3
add3 :: Num a => a -> a -> a
Upvotes: 10