Skip to content

Instantly share code, notes, and snippets.

@ivan-kleshnin
Created February 9, 2016 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan-kleshnin/00e644470e57d38239c1 to your computer and use it in GitHub Desktop.
Save ivan-kleshnin/00e644470e57d38239c1 to your computer and use it in GitHub Desktop.
let assert = require("assert");
function curryN(N, fn) {
let self = undefined;
let collectFn = Object.defineProperties(function (...args) {
if (this) {
self = this;
}
if (args.length >= N) {
return fn.apply(self, args);
}
else {
return Object.defineProperties(function (...args2) {
return collectFn.apply(this, args.concat(args2));
}, {
name: {value: fn.name},
length: {value: N - args.length},
});
}
}, {
name: {value: fn.name},
length: {value: N}
});
return collectFn;
}
let curry = function (fn) {
return curryN(fn.length, fn);
};
let sum3 = curry(function mySum(x, y, z) {
if (this) {
return [x + y + z, this];
} else {
return x + y + z;
}
});
// TEST LOGIC
assert.equal(typeof sum3(1), "function");
assert.equal(typeof sum3(1, 2), "function");
assert.equal(typeof sum3(1)(2), "function");
assert.equal(sum3(1)(2)(3), 6);
// TEST NAMES
assert.equal(sum3.name, "mySum");
assert.equal(sum3(1).name, "mySum");
assert.equal(sum3(1, 2).name, "mySum");
assert.equal(sum3(1)(2).name, "mySum");
// TEST LENGTHS
assert.equal(sum3.length, 3);
assert.equal(sum3(1).length, 2);
assert.equal(sum3(1, 2).length, 1);
assert.equal(sum3(1)(2).length, 1);
// TEST this BINDING
assert.deepEqual(sum3.bind({foo: "foo"})(1, 2, 3), [6, {foo: "foo"}]);
assert.deepEqual(sum3(1).bind({foo: "foo"})(2, 3), [6, {foo: "foo"}]);
assert.deepEqual(sum3(1, 2).bind({foo: "foo"})(3), [6, {foo: "foo"}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment