5 ms·
Eliminating the repetitive plumbing is a feature of haskell, not a feature of the monad. What the continuation monad gets you is a pipeline of asynchronous and
by lojack 9y ago
Eliminating the repetitive plumbing is a feature of haskell, not a feature of the monad. What the continuation monad gets you is a pipeline of asynchronous and synchronous operations. Whether or not something is asynchronous is abstracted away. Your example could be rewritten as:
composeAsync([
fetchUser("url"),
function(user) { return user.address },
fetchAddress,
function(address) { return address.zipcode }
]).then(function(output) {
document.write("Zipcode: " + output);
});
In this example you don't need to care if fetchAddress is synchronous or asynchronous, it'll work either way.
Its at least worth noting that one thing Haskell gives you is the ability to perform assignment within the async functions. This is also possible with Javascript, but a bit more intuitive in Haskell. Again, this is a feature of haskell, not a feature of monads.
var outputs = {};
composeAsync([
fetchUser("url"),
function(output) { outputs['user'] = output },
function() { return outputs.user.address },
fetchAddress,
function(output) { outputs['address'] = output }
]).then(function(output) { ... });
composeAsync could also be rewritten to store this in an accumulator, making it look a little nicer.
- pka 9y agoThis is not as general as a monad though, it's just feeding the output of one function into the next. I'm sure you know this, but the thing that makes monads a more general solution is that (because bind depends on a value produced at runtime) one can dynamically alter control flow, i.e: fetch = do user <- fetchUser "url" if userEmpty user then do fetchUserDetails "details" fetch -- recurse else fetchAddress user For that to work, your functions inside the `composeAsync` array would need to able to return nested promises and at that point you've just reimplemented the continuation monad :)
- lojack 9y agoYeah, I guess I may have not completely implemented the continuation monad, but my point was precisely what you just said. That is, it's totally possible to implement continuation monads in vanilla javascript. It's not only possible, but its reasonably easy to do without heavy lifting.
- rbalicki 9y agoJS has language level support for that now, too! async function getThings() { const user = await fetchUser(url) const address = await fetchAddress(user.address) return address.zipcode } // in some code getThings().then(zip => document.write(zip))