2017-04-06 24 views
4

当我这样定义函数中ghci的:ghci中的liftM:为什么会有这样的区别?

> :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 probl.hs 
:然后通过ghci中运行这个文件

我得到了这样的消息:

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. 

为什么会有这种区别?以及如何解决第二种情况的问题(我想要像第一个一样的行为)?

+0

我现在可以看到,这个问题的答案是属于单态限制的话题,但问题点均在ghci中的行为和liftM里面。我认为它有点不同。 – Vladimir

回答

3

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

Further reading