我开始阅读The Mother of All Monads,并输入了这个例子:
import Control.Monad.Cont
ex1 = do
a <- return 1
b <- return 10
return $ a+b
但是我遇到了编译时错误:
ghci> :l ContMonad.hs
[1 of 1] Compiling Main ( ContMonad.hs, interpreted )
ContMonad.hs:4:4:
No instance for (Monad m0) arising from a do statement
The type variable ‘m0’ is ambiguous
Relevant bindings include
ex1 :: m0 Integer (bound at ContMonad.hs:3:1)
Note: there are several potential instances:
instance Monad ((->) r) -- Defined in ‘GHC.Base’
instance Monad IO -- Defined in ‘GHC.Base’
instance Monad [] -- Defined in ‘GHC.Base’
...plus six others
In a stmt of a 'do' block: a <- return 1
In the expression:
do { a <- return 1;
b <- return 10;
return $ a + b }
In an equation for ‘ex1’:
ex1
= do { a <- return 1;
b <- return 10;
return $ a + b }
Failed, modules loaded: none.
如何让这个简单的例子进行类型检查?
答案 0 :(得分:11)
问题是ex1
作为表达式适用于任何 monad,并且未指定使用的monad。 ex1
的类型很可能是ex1 :: (Num b, Monad m) => m b
但是,由于dreaded monomorphism restriction,GHC无法推断出这种多态类型,因此结果不明确。
你可以通过给它一个显式的类型签名或禁用单态限制来编译它:
{-# LANGUAGE NoMonomorphismRestriction #-}
在GHCi中使用此功能时,由于extended default rules,它会自动将ex1
的值默认为IO Int
:
*Main> ex1
11
这些规则的存在是为了使ghci可用作计算器并提示执行IO操作。
您还应该尝试与其他一些monad一起看看会发生什么:
*Main> ex1 :: [Int]
[11]
*Main> ex1 :: Maybe Int
Just 11