Reputation: 959
So recently I discovered that you can do partial functions/currying with js using bind. For example:
const foo = (a, b, c) => (a + (b / c))
foo.bind(null, 1, 2) //gives me (c) => (1 + (2 / c))
However this only works if the parts you want to curry are in order. What if I wanted to achieve the following using bind?
(b) => (1 + (b / 2))
Tried various solutions such as:
foo.bind(null, 1, null, 2)
Any ideas? Is it possible to accomplish this with vanilla es6?
Upvotes: 4
Views: 718
Reputation: 1
you can wrap it in a function
const foo = (a, b, c) => (a + (b / c))
_ => foo(1, _, 2) //gives you (b) => (1 + (b / 2))
Upvotes: 0
Reputation: 386512
You could use a wrapper for a reordering of arguments.
const
foo = (a, b, c) => a + b / c,
acb = (a, c, b) => foo(a, b, c);
console.log(acb.bind(null, 1, 2)(5));
Upvotes: 4
Reputation: 3115
Currently I think about two ways to implement this (besides the wrapper from @NinaSholz, which is pretty nice):
curry
function that merges two argument arrays:const foo = (a, b, c) => a + b / c;
function curry(fn, ...args) {
return function(...newArgs) {
const finalArgs = args.map(arg => arg || newArgs.pop());
return fn(...finalArgs);
};
}
const curriedFoo = curry(foo, 1, null, 2);
console.log(curriedFoo(4)) // Should print 1 + 4 / 2 = 3
Here we are just sending null
or undefined
in the place of the parameters we want to skip and in the second call we send those parameters in order
const foo = ({a, b, c}) => a + b / c;
function curry(fn, args) {
return (newArgs) => fn({ ...args,
...newArgs
});
}
const curriedFoo = curry(foo, {
a: 1,
c: 2
});
console.log(curriedFoo({
b: 4
}));
Here we are taking advantage of the ...
(spread) operator and object syntax in the funcion signature to merge two argument objects;
Upvotes: 0