Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ask HN: Is this a monad?
1 point by Johngibb on Feb 11, 2011 | hide | past | favorite | 1 comment
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.

Am I at all on the right track?

  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)))


I think you'll be better off asking this on stack exchange.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: