

Ask HN: Is this a monad? - Johngibb

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 &#60; 10 &#38;&#38; y &#60; 10 ) {
      return { value: x + y };
    }
    else {
      return { error: "Num over 10" };
    }
  }

  ///////////////////////////////////////////////////
  // This takes in a function f(x) =&#62; y, and creates
  // a function f(x) =&#62; 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) =&#62; 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>
======
georgecmu
I think you'll be better off asking this on stack exchange.

