继续传递风格vs monads

连续传递样式(cps)和monad之间有什么区别。     
已邀请:
如功能编程的本质所述:   使用monad编程强烈让人想起延续传递风格(CPS),本文探讨了两者之间的关系。从某种意义上说,它们是等价的:CPS作为monad的特例出现,任何monad都可以通过改变答案类型嵌入到CPS中。但是monadic方法提供了额外的洞察力并允许更精细的控制。 那篇论文非常严谨,实际上并没有完全扩展CPS和monad之间的关系。在这里,我试图给出一个非正式的,但说明性的例子: (注意:以下是对新手(我自己)的Monad的理解,虽然在写完之后看起来看起来像是那些高代表用户的回答之一。请大量拿盐) 考虑经典的
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时,任何计算必须停止。这有点像说“一个可能的计算必须停止并且尽快返回
Nothing
”链中的任何值都是
Nothing
)。让我们看看如何通过编写“CPS变换器”来做到这一点。
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
请注意,最终返回值可以是
undefined
,但这很好,因为评估在第3步(
z
)停止。 我们可以看到
cap10
用一些额外的逻辑“包裹”正常的延续。这与monad非常接近 - 将计算与一些额外的逻辑相结合。 让我们更进一步:
(>>==) :: ((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
WOA!也许我们刚刚发明了
Cap10
monad! 现在,如果我们查看Cont的源代码,我们会看到
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的作者完全控制。     
你可能想看看这个http://blog.sigfpe.com/2008/12/mother-of-all-monads.html     
一篇探讨这个问题的有趣论文是Peyton Jones和Wadler的“势在必行的函数式编程”。 这是引入monadic IO的论文,它与包括CPS在内的替代方法进行了比较。 作者得出结论:   因此monad比continuation更强大,但仅仅因为类型!目前尚不清楚这是否只是欣德利 - 米尔纳式系统的一个人工制品,或者这些类型是否揭示了基本重要性的差异(我们自己的直觉是后者 - 但它只是一种直觉。)     
没有关系,因此这个问题与询问蓝色和冥王星之间的区别同样有意义。     

要回复问题请先登录注册