在ghci liftM:为什么会有这样的差异?

时间:2017-04-06 12:19:40

标签: haskell monads ghci lifting

当我在ghci中定义这样的函数时:

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

他们运作良好:

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

但是当我在文件中定义相同的函数时(probl.hs):

 import Control.Monad

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

 g = liftM f

然后通过ghci:

运行此文件
 ghci probl.hs

我收到了这样的消息:

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.

为什么会有这样的差异?如何用第二种情况解决问题(我想要像第一种情况一样的行为)?

1 个答案:

答案 0 :(得分:3)

你被可怕的单态限制所击中!这是一个非直观的规则,在GHCi中关闭,但在编译时。使用类型签名(推荐)或{-# LANGUAGE NoMonomorphismRestriction #-}禁用它。基本上,它有时会使没有类型签名的表达式比您预期的更具多态性。

Further reading