|
|
|
|
|
by kccqzy
2612 days ago
|
|
This code fn some_wlroots_callback(output_handle: OutputHandle,
surface_handle: SurfaceHandle) {
output_handle.run(|output| {
surface_handle.run(|surface| {
// maybe some more nested layers...
}).unwrap()
}).unwrap()
}
is just screaming continuation monad. You see the same code pattern in early Node.js code (sometimes leading to callback hell). In the JavaScript world, the problem was solved using Promises, and then async/await syntax. But more fundamentally, this is an instance of the continuation monad at work.The continuation monad transformer is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }
and is nothing more than just a function that takes a callback. If this were Haskell, one could just write stuff = runContT $ do
output <- ContT (run outputHandle)
surface <- ContT (run surfaceHandle)
-- and then maybe some more nested layers
-- etc
Granted, continuation code can easily be misused to produce an incomprehensible mess in Haskell (its full generality can be compared with goto), but with Rust's FnOnce trait, the scope for misuse is considerably reduced. |
|