I'm trying to wrap my head around what a monad is, and I think I
may finally understand it. I've tried coming up with an example
in javascript, since it's a fairly functional language with which
I'm pretty familiar.<p>Am I at all on the right track?<p><pre><code> puts = require('sys').puts;
///////////////////////////////////////////////////
// if x and y are less than 10, they will be added
// together. otherwise, an error will be displayed
///////////////////////////////////////////////////
function addNumsUnder10(x, y){
if ( x < 10 && y < 10 ) {
return { value: x + y };
}
else {
return { error: "Num over 10" };
}
}
///////////////////////////////////////////////////
// This takes in a function f(x) => y, and creates
// a function f(x) => M y, where M is an error
// Monad.
///////////////////////////////////////////////////
function unit(f){
return function(){
return { value: f.apply(this, arguments) };
}
}
///////////////////////////////////////////////////
// this combines two functions, who each do a
// mapping of f(*args) => M y, where M is an error
// Monad.
///////////////////////////////////////////////////
function bind(fa, fb){
return function(){
var ret = fb.apply(this, arguments);
if ( ret.error ){
return { error: ret.error };
}
else {
var val = ret.value;
return fa(val);
}
}
}
///////////////////////////////////////////////////
// this function will print either the return
// value of the functions called, or the error
// message passed up through the Error monad.
///////////////////////////////////////////////////
function printOutput(o){
if (o.error){
return "Error: " + o.error;
}
else {
return "Value: " + o.value;
}
}
///////////////////////////////////////////////////
// this is a regular function, unaware of the
// error Monad. To be combined with error-aware
// functions, it must be wrapped with the unit.
///////////////////////////////////////////////////
function add5(n){
return n + 5;
}
var addTwoNumsPlus5 =
bind(
unit(add5),
addNumsUnder10
);
puts(printOutput(addTwoNumsPlus5(4, 5)))
puts(printOutput(addTwoNumsPlus5(4, 15)))</code></pre>