haskellmonadsghcilifting

liftM in ghci: why is there such difference?


When I define such functions inside ghci:

> :m Control.Monad
> let f n = n+1
> let g = liftM f

they work well:

> g $ Just 2
> Just 3
> g $ [1,2]
> [2,3]

But when I define the same functions in file (probl.hs):

 import Control.Monad

 f :: Integer -> Integer
 f n = n + 2

 g = liftM f

and then run this file via ghci:

 ghci probl.hs

I got such message:

probl.hs:6:5: error:
    * Ambiguous type variable `m0' arising from a use of `liftM'
      prevents the constraint `(Monad m0)' from being solved.
      Relevant bindings include
        g :: m0 Integer -> m0 Integer (bound at probl.hs:6:1)
...
Failed, modules loaded: none.

Why is there such difference? And how to solve problem with second situation (I want the same behavior like in first one)?


Solution

  • You are being hit by the dreaded Monomorphism Restriction! It is an unintuitive rule that is turned off in GHCi, but on when you compile. Use a type signature (recommended), or {-# LANGUAGE NoMonomorphismRestriction #-} to disable it. Basically, it sometimes makes expressions without type signatures less polymorphic than you would expect.

    Further reading