Skip to content

Instantly share code, notes, and snippets.

@briancavalier
Forked from unscriptable/curry.js
Last active August 29, 2015 14:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save briancavalier/d2385e8fbca53c8d056b to your computer and use it in GitHub Desktop.
Save briancavalier/d2385e8fbca53c8d056b to your computer and use it in GitHub Desktop.
module.exports = curry;
function curry (f) {
var arity = f.length;
var params = [];
var end = createEnd(f, arity);
return createCurried(params, arity, end);
}
function createEnd (f, arity) {
var src = 'return function ' + f.name + '_curried (args) { return f(';
for (var i = 0; i < arity; i++) {
src += (i ? ', args[' : 'args[') + i + ']';
}
src += '); };';
return (new Function ('f', src)(f));
}
function createCurried (collected, arity, end) {
return function () {
var params = concat(collected, arguments);
return params.length < arity
? createCurried(params, arity, end)
: end(params);
};
}
function concat(a, b) {
var al = a.length;
var bl = b.length;
var c = new Array(al + bl);
var i;
for(i=0; i<al; ++i) {
c[i] = a[i];
}
for(i=0; i<bl; ++i) {
c[i+al] = b[i];
}
return c;
}
function add(x, y) {
return x + y;
}
var addc = curry(add);
var z = addc(1)(2);
console.log(z);
@briancavalier
Copy link
Author

This variant of @unscriptable's original version uses an extra dynamic compilation wrapper (line 16), to allow naming the last function in the curry chain, which could make debugging easier. It probably has similar perf characteristics.

@briancavalier
Copy link
Author

Update: I added a hand-coded concat() for appending arguments. It's significantly faster than using Array.prototype.concat + slice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment