Here and here it is said that the Continuation Monad solves the callback hell.
RX and FRP also solve the Callback hell.
If all these three tools solve the Callback hell then the following question arises:
In Erik's video it is said that RX=Continuation Monad. Is that really true? If yes, could you show the mapping?
IF RX is not = Cont. Monad then what is the difference between RX and Continuation Monad?
Similarly, what is the difference between FRP and the Continuation Monad ?
In other words, assuming that the reader knows what FRP or RX is, how can the reader easily understand what the Continuation Monad is ?
Is it possible/easy to understand what the Continuation Monad is by comparing it with RX or FRP ?
I'm not familiar with RX, but regarding FRP and the continuation monad, they're fundamentally different concepts.
Functional reactive programming is a solution to the problem of working with time-dependent values and events. With events, you can solve the callback problem by sequencing computations in such a way that when one finishes, an event is sent and it triggers the next one. But with callbacks you really don't care about time, you just want to sequence computations in a specific way, so unless your whole program is based on FRP, it's not the optimal solution.
The continuation monad has nothing to do with time at all. It's an abstract concept of computations that can (loosely speaking) take "snapshots" of the current evaluation sequence and use them to "jump" to those snapshots arbitrarily. This allows to create complex control structures such as loops and coroutines. Now have a look at the definition of the continuation monad:
newtype Cont r a = Cont { runCont :: (a -> r) -> r}
This is essentially a function with a callback! It's a function that accepts a continuation (callback) that will continue the computation after a
is produced. So if you have several functions that take continuations,
f1 :: (Int -> r) -> r
f2 :: Int -> (Char -> c) -> c
f3 :: Char -> (String -> d) -> d
their composition becomes somewhat messy:
comp :: String
comp = f1 (\a -> f2 a (\b -> f3 b id))
Using continuations, it becomes very straightforward, we just need to wrap them in cont
and then sequence them using the monadic bind operaiton >>=
:
import Control.Monad.Cont
comp' :: String
comp' = runCont (cont f1 >>= cont . f2 >>= cont . f3) id
So continuations are a direct solution to the callback problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With