Search code examples
haskellghcghci

ghci shows type as being concrete


I have the following code:

{-# LANGUAGE GADTs #-}
data Exp' a where
  Float' :: (Num a) => Float -> Exp' a
g = Float' 1.2

If I type the above code directly into ghci, and check g's type, I'd get:

GHCI> let g = Float' 1.2
GHCI> :t g
g :: Num a => Exp' a

The above is what I expected.

However, when loading a file with the above code, I'd get this instead:

GHCI> :load <filename>
GHCI> :t g
g :: Exp' Integer

Any idea why the behaviors are different? Thanks in advance.


Solution

  • This behavior is caused by the monomorphism restriction which is enabled in source files, but disabled in GHCi.

    Basically, the rule is that variable bindings without arguments are always inferred to have a concrete type. In your case the binding g = Float' 1.2 doesn't have arguments, so it's Num constraint will be defaulted to Integer when inferring types.

    You can see that the behavior changes if you add a dummy argument:

    g () = Float' 1.2
    

    Or if you just disable the monomorphism restriction:

    {-# LANGUAGE NoMonomorphismRestriction #-}