Cont的monad实例有什么用?

Seb*_*raf 7 monads haskell 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')
Run Code Online (Sandbox Code Playgroud)

可以很容易地重写为

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

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

我缺乏想象力想出一个例子.宣布Cont rmonad 我们实际上得到了什么?

Mic*_*man 9

你可以问同样的问题的任何 Monad.在我的头脑中,我可以想到三个优点:

  1. 您可以访问旨在与Monads 一起使用的大量函数.
  2. 你可以使用do-notation.
  3. 你可以叠加monad变换器来创建更强大的东西.

这也允许您更好地推理您的代码,因为您可以依赖身份和关联属性等.


Lee*_*Lee 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
Run Code Online (Sandbox Code Playgroud)

这个函数不依赖于monad Cont,可以用更通用的类型编写,例如

sumOfSquaresM :: Monad m => m Int -> m Int -> m Int
Run Code Online (Sandbox Code Playgroud)