Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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