Skip to content

Instantly share code, notes, and snippets.

@neftaly
Last active April 10, 2022 18:47
Show Gist options
  • Save neftaly/b77455b3df9a8b50bf8b to your computer and use it in GitHub Desktop.
Save neftaly/b77455b3df9a8b50bf8b to your computer and use it in GitHub Desktop.
ES6 Auto-curry
const curry = (fn, ...oldArgs) => (...newArgs) => {
const args = [...oldArgs, ...newArgs];
return (args.length < fn.length) ? curry(fn, ...args) : fn(...args);
};
const curryN = (arity, fn) => {
const receiver = preArgs => (...postArgs) => {
const args = [...preArgs, ...postArgs];
return (args.length < arity) ? receiver(args) : fn(...args);
}
return receiver([]);
}
const curry = fn => curryN(fn.length, fn);
const curryN = (arity, fn) => {
// Take old arguments, and an array of new arguments
const receiver = oldArgs => (...newArgs) => {
const args = [...oldArgs, ...newArgs]; // Combine old and new arguments
if (args.length >= arity) { // Have enough arguments have been received?
return fn(...args); // Run fn with argument list
}
return receiver(args); // Recurse, and await further arguments
};
return receiver([]); // Start with an empty array of prior arguments
};
const curry = fn => curryN(fn.length, fn);
const add3 = function (a, b, c) {
return a + b + c;
};
const x = curry(add3);
x(1)(1)(1); //=> 3
x(1, 1)(1); //=> 3
x(1, 1, 1); //=> 3
@meChrisReed
Copy link

I like what you have here.
I think you can reduce this to:

const curry = (fn, ...args) => (
  args.length === fn.length ?
    fn(...args) :
    curry.bind(null, fn, ...args)
);

const add3 = curry((a,b,c) => a+b+c);
add3(1)(1)(1); //=> 3
add3(1, 1)(1); //=> 3
add3(1, 1, 1); //=> 3

Please let me know your thoughts or if there is some functionality lost.

@neftaly
Copy link
Author

neftaly commented Jun 21, 2016

Looks good! This was actually for explaining how auto-currying worked in a talk, so I wouldn't have used bind (too much cognitive load for audience), but it'd be great otherwise.

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