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是什么?
我对 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)
所以延续是回调问题的直接解决方案。