haskellpolymorphismtype-inferencemonomorphism-restriction

Why are polymorphic values not inferred in Haskell?


Numeric literals have a polymorphic type:

*Main> :t 3
3 :: (Num t) => t

But if I bind a variable to such a literal, the polymorphism is lost:

x = 3
...
*Main> :t x
x :: Integer

If I define a function, on the other hand, it is of course polymorphic:

f x = 3
...
*Main> :t f
f :: (Num t1) => t -> t1

I could provide a type signature to ensure the x remains polymorphic:

x :: Num a => a
x = 3
...
*Main> :t x
x :: (Num a) => a

But why is this necessary? Why isn't the polymorphic type inferred?


Solution

  • It's the monomorphism restriction which says that all values, which are defined without parameters and don't have an explicit type annotation, should have a monomorphic type. This restriction can be disabled in ghc and ghci using -XNoMonomorphismRestriction.

    The reason for the restriction is that without this restriction long_calculation 42 would be evaluated twice, while most people would probably expect/want it to only be evaluated once:

    longCalculation :: Num a => a -> a
    longCalculation = ...
    
    x = longCalculation 42
    
    main = print $ x + x