我正在玩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是什么意思?
答案 0 :(得分:9)
您可以提出与任何 Monad
相同的问题。在我的头脑中,我可以想到三个优点:
Monad
一起使用的大量函数。do
- 表示法。这也可以让你更好地推理你的代码,因为你可以依赖身份和关联属性等。
答案 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