Following on from my introduction to monads in JavaScript, and before I get into how they apply to asynchronous programming, I’d like to take a quick detour to improve the usability of the tools we’ve built up. Recall we have a function for composing functions:

var compose = function ( f , g ) { return function ( x ) { return f ( g ( x )) }; };

We have some ‘debuggable’ functions:

// sine :: Number -> (Number,String) var sine = function ( x ) { return [ Math . sin ( x ), ' sine was called. ' ]; }; // cube :: Number -> (Number,String) var cube = function ( x ) { return [ x * x * x , ' cube was called. ' ]; };

And finally we have the unit and bind functions for the ‘debuggable’ monad:

// unit :: Number -> (Number,String) var unit = function ( x ) { return [ x , '' ] }; // bind :: (Number -> (Number,String)) -> ((Number,String) -> (Number,String)) var bind = function ( f ) { return function ( tuple ) { var x = tuple [ 0 ], s = tuple [ 1 ], fx = f ( x ), y = fx [ 0 ], t = fx [ 1 ]; return [ y , s + t ]; }; };

These let us compose our debuggable functions to create new debuggable functions:

var f = compose ( bind ( sine ), bind ( cube )); f ( unit ( 3 )) // -> [0.956, 'cube was called.sine was called.']

This is all well and good, but we should really be able to compute sin(x^3) as a one-liner. With the code we have, this expression would be:

bind ( sine )( bind ( cube )( unit ( 3 )))

This is hardly convenient, especially when I tell you that the equivalent Haskell expression is:

return 3 >>= cube >>= sine

This reads like a pipeline: take 3 , pass it through cube , then pass the result of that through sine . In Haskell, unit is called return , and bind is actually an operator (or infix function) called >>= . The operator >>= doesn’t just convert functions into composable form, it takes a monadic value – in our example, a (Number,String) tuple – and a debuggable function, and deals with unpacking the value from the monad, applying the function to it, and combining the result with the monad in a meaningful way.

Using our existing names, a direct translation to JavaScript of this would be:

bind ( bind ( unit ( 3 ), cube ), sine )

Where the bind function now looks like this:

// bind :: (Number,String) -> (Number -> (Number,String)) -> (Number,String) var bind = function ( x , f ) { // e.g. x = [3, ''], f = cube var y = x [ 0 ], // 3 s = x [ 1 ], // '' fy = f ( y ), // cube(3) = [27, 'cube was called.'] z = fy [ 0 ], // 27 t = fy [ 1 ]; // 'cube was called.' return [ z , s + t ]; };

This representation is clearer, but not quite as expressive as the Haskell version. Let’s go one step forward:

var y = pipe ( unit ( 3 ), [ cube , sine ])

This seems reasonably close to Haskell’s version, and to go any further we’d really need some syntactic abstractions that JavaScript does not have. This pipe function is straightforward to implement: it takes a monadic value, and uses bind to pipe it through the list of debuggable functions:

// pipe :: (Number,String) -> [Number -> (Number,String)] -> (Number,String) var pipe = function ( x , functions ) { for ( var i = 0 , n = functions . length ; i < n ; i ++ ) { x = bind ( x , functions [ i ]); } return x ; };

We can easily use this with anonymous inline functions without losing much expressiveness:

var z = pipe ( unit ( 7 ), [ function ( x ) { return [ x + 1 , ' inc. ' ] }, function ( x ) { return [ 2 * x , ' double. ' ] }, function ( x ) { return [ x - 1 , ' dec. ' ] } ]) // z == [15, 'inc.double.dec.']