Cont的monad实例有什么用?

时间:2014-06-10 18:02:50

标签: haskell monads continuation-passing

我正在玩CPS和Control.Monad.Cont并想知道我们通过注意monadic结构获得了什么。对于这样的代码:

sumOfSquares'cps :: Cont r Int -> Cont r Int -> Cont r Int
sumOfSquares'cps x y = x >>= \x' ->
                       y >>= \y' ->
                       return (x'*x' + y'*y')

可以轻松改写为

type Cont' r a = (a -> r) -> r

sos'cps :: Cont' r Int -> Cont' r Int -> Cont' r Int
sos'cps x y = \k -> x $ \x' -> 
                    y $ \y' -> 
                    k (x'*x' + y'*y') 

不要误会我的意思,但除了能够使用do符号和newtype之外,我无法看到这种感觉。我不认为callCC依赖于monad实例。

我缺乏想象力想出一个例子。我们实际宣布Cont r monad是什么意思?

2 个答案:

答案 0 :(得分:9)

您可以提出与任何 Monad相同的问题。在我的头脑中,我可以想到三个优点:

  1. 您可以访问旨在与Monad一起使用的大量函数。
  2. 您可以使用do - 表示法。
  3. 你可以叠加monad变形金刚来创造更强大的东西。
  4. 这也可以让你更好地推理你的代码,因为你可以依赖身份和关联属性等。

答案 1 :(得分:6)

一个明显的优势是您可以使用为Monads(和Functors)定义的组合子。例如,您的函数可以使用liftM2

编写
sumOfSquares'cps :: Cont r Int -> Cont r Int -> Cont r Int
sumOfSquares'cps = liftM2 sumSquares
  where sumSquares x y = x * x + y * y

此函数不依赖monad为Cont,并且可以用更通用的类型编写,例如

sumOfSquaresM :: Monad m => m Int -> m Int -> m Int