In my previous post I talked about JavaScript being a functional language. But those familiar with traditional functional languages like Haskell and ML will notice that JavaScript lacks traditional functional constructs like map, foldl and currying.
I do wish that JavaScript had these constructs by default, and it doesn’t. But at least we can add these constructs ourselves.
var map = function(fn , xs) {
if (xs.length == 1) return [fn(xs[0])];
return [fn(xs[0])].concat(map(fn, xs.slice(1)));
};
var foldl = function(fn , x0, xs) {
if (xs.length == 1) return fn(x0, xs[0]);
return foldl(fn, fn(x0, xs[0]), xs.slice(1) );
};
var curry = function(fn) {
/* Yes, I hate this function, why do you ask? */
function toArray(pseudoarray) {
var array = [];
for (var i=0; i<pseudoarray.length; i++)
array.push(pseudoarray[i]);
return array;
}
var xs = toArray(arguments).slice(1);
return function() {
return fn.apply(this, xs.concat(toArray(arguments)));
};
};
Then you can do things like:
/* Ex 1 */
var double = function(x) {return 2*x};
map(double, [1,2,3,4,5]);
/* Ex 2 */
var mult = function(x,y) { return x*y };
foldl(mult, 1, [2,3,4,5]);
/* Ex 3 */
var product = function(xs) {
return foldl(function(x,y) { return x*y }, 1, xs);
};
product([1,2,3,4,5]);
/* Ex 4 */
var add = function(a,b) { return a+b; }
var add1 = curry(add, 1);
add1(2);