There is already a Monad based solution - its Deferreds / Promises.
However, monads don't solve this problem - they cause it, since their primary concern is correctness and not converting between monadic and non-monadic code.
If you have a pure function and need to convert it to a monadic action there will be lots of collateral damage as functions that interacted with the old function have to be converted to monadic style.
Yeah, just after I wrote that I realized that Deferreds/Promises are monads.
You don't have to convert them, but you do need a way to write code using those pure functions "inside" the monad which I don't think is easy with this model.
You should be able to just chain your actions together, with a wrapper function to turn pure functions into actions. I don't see why you would need to convert the actual pure functions to monadic style.
I guess what I had in my head when I made the comment was the convenience functions or the syntactic sugar around a monadic solution. Seems like the node guys are playing with things like this but all the solutions I've seen seem so ugly.
Pure code can be used in the monad just fine, (ie.: you can return values up to the monad and lift functions)
//turn a function into a monadic action
function lift(f){ return function(/**/){
var d = new Deferred(); //Im using the Dojo API
d.resolve( f.call(this, arguments) );
return d.promise;
};};
var f = function(x){ return x+1}
lift(f)(0)
.then(function(y){ ... })
The problem is the opposite direction: pure code using monadic code and pure code turning into monadic code
If you have something like
var x = f1( f2( f3() ) )
And f2 becomes a monadic action you have to rewrite this bit as
var xPromise = f2( f3() )
.then(function(f2result){
return f1(f2result);
});
However, monads don't solve this problem - they cause it, since their primary concern is correctness and not converting between monadic and non-monadic code. If you have a pure function and need to convert it to a monadic action there will be lots of collateral damage as functions that interacted with the old function have to be converted to monadic style.