使用ContT构造器创建新的Monad Cont

Kev*_*ith 3 haskell

我开始阅读所有Monads的母亲,并输入了这个例子:

import Control.Monad.Cont

ex1 = do
  a <- return 1
  b <- return 10
  return $ a+b
Run Code Online (Sandbox Code Playgroud)

但是我遇到了一个编译时错误:

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.
Run Code Online (Sandbox Code Playgroud)

我怎样才能将这个简单的例子用于类型检查?

Tik*_*vis 11

问题是ex1因为表达式适用于任何 monad,并且未指定使用的monad.该类型的ex1很可能是ex1 :: (Num b, Monad m) => m b,但是,因为的可怕的单态的限制,GHC不能推断出这种多态类型,这样结果是不明确的.

你可以通过给它一个显式类型签名或禁用单态限制来编译它:

{-# LANGUAGE NoMonomorphismRestriction #-}
Run Code Online (Sandbox Code Playgroud)

在GHCi中使用它时ex1,IO Int由于扩展的默认规则,它会自动默认值的值为:

*Main> ex1
11
Run Code Online (Sandbox Code Playgroud)

存在这些规则使ghci可用作计算器并提示执行IO操作.

您还应该尝试与其他一些monad一起看看会发生什么:

*Main> ex1 :: [Int]
[11]
*Main> ex1 :: Maybe Int
Just 11
Run Code Online (Sandbox Code Playgroud)

  • 如果你真的想使用continuation monad,你可以说像`runCont ex1 id`甚至`runCont ex1 print`. (2认同)