Typeclass mimic in JavaScript (2)

by julienrf

JavaScript

function Option() {}
Option.fmap = function (f, o) {
    if (o instanceof Some) {
        return new Some(f(o._value));
    } else {
        return new None;
    }
};

function Some(value) {
    this._value = value;
}

function None() {}

function List(array) {
    this._array = array;
}
List.fmap = function (f, xs) {
    return new List(xs._array.map(f));
};

function plus1(n) { return n + 1; }

// Reusable code.
function fplus1(functor, value) {
    return functor.fmap(plus1, value);
}

var o1 = new Some(42);
var o2 = new None;
var l = new List([1, 2, 3]);

console.log(fplus1(Option, o1), fplus1(Option, o2));
console.log(fplus1(List, l));


var Int = {
    mzero: 0,
    mappend: function (a, b) { return a + b; }
};

var Text = {
    mzero: '',
    mappend: function (a, b) { return a + b; }
};

List.mzero = [];
List.mappend = function (a, b) { return a.concat(b); };

function concat(monoid, xs) {
    return xs.reduce(monoid.mappend, monoid.mzero);
}

var ints = [1, 2, 3, 4, 5];
var texts = ['1', '2', '3', '4', '5'];
var lists = [[1, 2], [3, 4], [5, 6]];

console.log(concat(Text, texts));
console.log(concat(Int, ints));
console.log(concat(List, lists));

// Inconvénient : il faut préciser manuellement l’instance de typeclass (Option, List, etc.)