Continuation Monad为什么以及如何解决回调地狱?换句话说:RX还是FRP = Continuation Monad?如果不是=,有什么区别?

jhe*_*dus 5 monads continuations haskell frp system.reactive

在这里,并在这里是说,延续单子解决回调地狱。

RX和FRP也解决了回调地狱。

如果所有这三个工具都解决了“回调地狱”,则会出现以下问题:

在Erik的视频中,据说RX = Continuation Monad。是真的吗 如果是,您可以显示映射吗?

如果RX不是=继续。Monad那么RX和Continuation Monad有什么区别?

同样,FRP和Continuation Monad有什么区别?

换句话说,假设读者知道FRP或RX是什么,那么读者如何轻松理解Continuation Monad是什么?

通过与RX或FRP进行比较,是否可能/容易理解Continuation Monad是什么?

Pet*_*lák 4

我对 RX 不熟悉,但是关于 FRP 和 Continuation monad,它们是根本不同的概念。

函数反应式编程是处理与时间相关的值和事件的问题的解决方案。使用事件,您可以通过对计算进行排序来解决回调问题,当一个事件完成时,发送一个事件并触发下一个事件。但是使用回调,您实际上并不关心时间,您只想以特定方式对计算进行排序,因此除非您的整个程序基于 FRP,否则它不是最佳解决方案。

延续单子与时间完全无关。这是一个抽象的计算概念,可以(宽松地说)获取当前评估序列的“快照”并使用它们任意“跳转”到这些快照。这允许创建复杂的控制结构,例如循环和协程。现在看一下延续单子的定义:

newtype Cont r a = Cont { runCont :: (a -> r) -> r}
Run Code Online (Sandbox Code Playgroud)

这本质上是一个带有回调的函数!它是一个接受延续(回调)的函数,该延续将在a生成后继续计算。所以如果你有几个需要延续的函数,

f1 :: (Int -> r) -> r

f2 :: Int -> (Char -> c) -> c

f3 :: Char -> (String -> d) -> d
Run Code Online (Sandbox Code Playgroud)

他们的组成变得有些混乱:

comp :: String
comp = f1 (\a -> f2 a (\b -> f3 b id))
Run Code Online (Sandbox Code Playgroud)

使用延续,它变得非常简单,我们只需要将它们包装起来cont,然后使用单子绑定操作对它们进行排序>>=

import Control.Monad.Cont

comp' :: String
comp' = runCont (cont f1 >>= cont . f2 >>= cont . f3) id
Run Code Online (Sandbox Code Playgroud)

所以延续是回调问题的直接解决方案。