延续传递样式(cps)和monad之间有什么区别。
答案 0 :(得分:23)
如The essence of functional programming中所述:
使用monad编程强烈让人想起延续传递风格(CPS),本文探讨了两者之间的关系。从某种意义上说,它们是等价的:CPS作为monad的特例出现,任何monad都可以通过改变答案类型嵌入到CPS中。但是monadic方法提供了额外的洞察力,并允许更精细的控制。
那篇论文非常严谨,实际上并没有完全扩展CPS和monad之间的关系。在这里,我试图给出一个非正式的,但是说明性的例子:
(注意:以下是新手(我自己)对Monad的理解,虽然在写完之后看起来看起来像是那些高代表用户的答案之一。请大量拿盐)< / p>
考虑经典的Maybe
monad
-- I don't use the do notation to make it
-- look similar to foo below
bar :: Maybe Int
bar =
Just 5 >>= \x ->
Just 4 >>= \y ->
return $ x + y
bar' :: Maybe Int
bar' =
Just 5 >>= \x ->
Nothing >>= \_ ->
return $ x
GHCi> bar
Just 9
GHCi> bar'
Nothing
一旦遇到Nothing
,计算就会停止,这里没什么新东西。让我们尝试使用CPS模仿这种monadic行为:
这是我们使用CPS的vanilla add
函数。我们在这里使用所有Int
而不是algebric数据类型来简化:
add :: Int -> Int -> (Int -> Int) -> Int
add x y k = k (x+y)
GHCi> add 3 4 id
7
注意它与monad的相似程度
foo :: Int
foo =
add 1 2 $ \x -> -- 3
add x 4 $ \y -> -- 7
add y 5 $ \z -> -- 12
z
GHCi> foo
12
行。假设我们希望计算的上限为10.也就是说,当下一步导致值大于10时,任何计算必须停止。这有点像说“一个可能计算必须停止并返回{{1} }只要链中的任何值都是Nothing
)。让我们看看如何通过编写“CPS变换器”来实现它
Nothing
请注意,最终返回值可以是cap10 :: (Int -> Int) -> (Int -> Int)
cap10 k = \x ->
if x <= 10
then
let x' = k x in
if x' <= 10 then x' else x
else x
foo' :: Int
foo' =
add 1 2 $ cap10 $ \x -> -- 3
add x 4 $ cap10 $ \y -> -- 7
add y 5 $ cap10 $ \z -> -- 12
undefined
GHCi> foo'
7
,但这很好,因为评估在第3步(undefined
)停止。
我们可以看到z
用一些额外的逻辑包装“正常的延续”。这与monad非常接近 - 将计算与一些额外的逻辑相结合。
让我们更进一步:
cap10
吁!也许我们刚刚发明了(>>==) :: ((Int -> Int) -> Int) -> (Int -> Int) -> Int
m >>== k = m $ cap10 k
foo'' :: Int
foo'' =
add 1 2 >>== \x -> -- 3
add x 4 >>== \y -> -- 7
add y 5 >>== \z -> -- 12
undefined
GCHi> foo''
7
monad!
现在,如果我们查看source code of Cont,我们会看到Cap10
是
Cont
newtype Cont r a = Cont { runCont :: (a -> r) -> r }
的类型是
runCont
与Cont r a -> (a -> r) -> r
((a -> r) -> r) -> (a -> r) -> r
现在输入所有内容后,我重新阅读原始问题。 OP要求“差异”:P
我猜不同之处在于CPS为调用者提供了更多控制权,而monad中的>>==
通常由monad的作者完全控制。
答案 1 :(得分:7)
答案 2 :(得分:4)
Peyton Jones和Wadler撰写的一篇探讨该问题的有趣论文是"Imperative functional programming"。
这是介绍monadic IO的论文,它与其他方法(包括CPS)进行了比较。
作者总结道:
所以monad比continuation更强大,但只是因为类型!目前尚不清楚这是否只是欣德利 - 米尔纳式系统的一个人工制品,或者这些类型是否揭示了基本重要性的差异(我们自己的直觉是后者 - 但它只是一种直觉。)
答案 3 :(得分:-10)
没有任何关系,因此问题与询问蓝色和冥王星之间的区别同样有意义。