// These need to be registered from general to specific. // The alternative I can see is to use a prototype-based solutions as done in: // https://github.com/loop-recur/typeclasses/blob/master/functor.js Functor(Array, {fmap: function(f, arr){ return arr.map(function(x){return f(x);}); }}); Functor(Function, {fmap: function(f, g) { return compose(f, g); }}); Functor(Maybe, {fmap: function(f, maybe) { return (maybe.val == null) ? maybe : Maybe(f(maybe.val)); }}); Functor(Either, {fmap: function(f, either) { return (either.right == null) ? Either(f(either.left), null) : Either(either.left, f(either.right)); }}); var plus1 = function(n) {return n + 1;}; var times2 = function(n) {return n * 2;}; console.log(fmap(plus1, [2, 4, 6, 8])); //=> [3, 5, 7, 9] console.log(fmap(plus1, Maybe(5))); //=> Maybe(6) console.log(fmap(plus1, Maybe(null))); //=> Maybe(null) console.log(fmap(plus1, times2)(3)); //=> 7 (= 3 * 2 + 1) console.log(fmap(plus1, Either(10, 20))); //=> Either(10, 21) console.log(fmap(plus1, Either(10, null))); //=> Either(11, null)