2017-04-06 72 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