yuxingdubai
yuxingdubai

Reputation: 53

Type inference of a function in GHCi differs with loaded from a file

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

Answers (1)

Sibi
Sibi

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

Related Questions