JS - Currying
by Jason Aden
JavaScript
// Crockford's example
// make an add1 method, based on add
// First... the curry method
// extends Function object prototype with a new method
// uses a closure to remember the args
Function.prototype.curry = function () {
// create a reference to the current function
// and the arguments (as an array)
var fn = this,
args = Array.prototype.slice.call(arguments);
// return the function, which will now be invoked
// with this context
// and the arguments provided are tacked onto the beginning
// of the arguments passed to the original function
return function () {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
}
function add(x, y) {
return x + y;
}
var add1 = add.curry(1);
console.log("Add1: ", add1(5));
// Partials
// John Resig/Oliver Steele take this a step further
// Ability to fill in missing arguments for a partial
/*
Function.prototype.partial = function () {
var fn = this,
args = Array.prototype.slice.call(arguments);
return function () {
var arg = 0;
// now we are looping through each argument
// and if the argument is undefined, we check for
// arguments passed to the curried function to fill it in
for (var i = 0; i < args.length && arg < arguments.length; i++) {
if (args[i] === undefined) {
args[i] = arguments[arg++];
}
}
return fn.apply(this, args);
};
};
// create a default 10 ms function
var delay = setTimeout.partial(undefined, 10);
/**/
// Partials with bind()
// Using bind() (es5) makes this trivial
/*
var add10 = add.bind(undefined, 10);
console.log("Add10: ", add10(1));
/**/