Monoids and monads

Here’s our definition of a monoid, slightly modified so you have to invoke the property 1 to get the identity element:

var monoidOf = function (m, n) {
  n = n || m;
  func(m); func(n);
  return makeInterface({
    '*': hom([m, m], n),
    1: hom([], n)
  });
};

Here’s a slight variant of this definition of a monoid:

var monadOf = function (m, n) {
  n = n || m;
  func(m); func(n);
  return function (intr) {
    return function (t) {
      return makeInterface({
        '*': hom([m(m(t))], n(t)),
        1: hom([t], n(t))
      })(intr);
    };
  };
};

Instead of the multiplication expecting a pair of functions, it expects the composite of functions. Here’s one way it’s used:

var flatten = monadOf(arrOf)({
  '*': function (arrayOfArrays) {
    var flattened = [], len = arrayOfArrays.length;
    for (var i = 0; i < len; ++i) {
      var innerLen = arrayOfArrays[i].length;
      for (var j = 0; j < innerLen; ++j) {
        flattened.push(arrayOfArrays[i][j]);
      }
    }
    return flattened;
  },
  1: function (x) { return [x]; }
});

var stringFlatten = flatten(str);

The stringFlatten example’s multiplication expects a doubly nested array of strings and returns an array of strings. It’s associative, in the sense that if you have a triply-nested array, it doesn’t matter if you flatten the inner or outer layer first. It’s unital in the sense that if you wrap a list in brackets and then flatten it, you get the same thing back; similarly if you wrap each element in brackets and flatten it, you also get the same thing back.

In a monoid, the multiplication wants two things and returns one; in a monad, the multiplication wants a functor applied twice to t and returns the functor applied once to t. In a monoid, the unit wants no elements and returns one; in a monad, the unit wants a functor applied no times to t and returns the functor applied once to t.

Monads are an exceptionally versatile design pattern. There are monads for lists, exceptions, simulating imperative programming on top of functional programming but still keeping the state explicit so you can mock out the state for easy testing, continuation passing style, parsing, promises (aka futures), event chaining, and more. jQuery, for example, is the combination of several of these monads.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: