3
votes

Loading a = 2+2.0 from a .hs file in GHCi and doing :t a shows a :: Double.

On the other hand, doing let b = 2+2.0 and :t b in GHCi shows b :: Fractional a => a.

How are you able to deduce this from these two documents?

I find this official documentation almost incomprehensible.

2

2 Answers

7
votes

This documentation is what you want, I think. Basically, GHC implements a different language by default in GHCi than in a module; in particular, the dreaded monomorphism restriction is enabled by default in a module (as per the language) whereas in GHCi it's disabled. The monomorphism restriction is what causes GHC to pick a monomorphic type for your a, whereas, with it turned off, GHC is free to generalize the type of b, yielding the polymorphic type you see.

2
votes

The key is that GHCi isn't defaulting the type of b. It takes the constraints 2 :: Num a => a and 2.0 :: Fractional a => a and unifies them to give 2 + 2.0 :: Fractional a => a. When it loads a module, the compiler forces every value to have a concrete type, so Fractional a is defaulted to Double.