const multiply = (x, y) => x * y;multiply(5, 10);// 50
But suppose we needed lots of functions that were similar but not the same. Let's say we needed to multiply lots of different pairs of numbers together, but many of these pairs have a number in common.
multiply(3, 6);multiply(3, 8);multiply(3, 22);multiply(5, 2);multiply(5, 9);multiply(5, 34);multiply(7, 4);multiply(7, 12);multiply(7, 999);
All this works, but it's repetitive and not too elegant. If the function being called was more complex, maintenance could quickly get out of hand.
This is where currying helps.
Coder: Normally I give you all the arguments at once. But instead I want you to save some arguments in a function, so when I call you I can just use the argument that's different. So when I call
multiply, I want you to remember I want one of the numbers to be 3. I'll just tell you what the different number is.
const multiply = x => x * 3;
Coder: Technically that would work, but I also want you to remember functions for the other common multipliers, like 5 and 7.
const multiplyBy3 = x => x * 3;const multiplyBy5 = x => x * 5;const multiplyBy7 = x => x * 7;
Coder: That's the end result I want, but rewriting that multiplication logic three times feels wasteful. I want to generate different versions of that function without rewriting it so much.
Coder: What if I wrote a function that would return another function? The first function is where I pass in the number I always want to multiply by, and that gives me another function that can multiply by another number?
const multiplyCurrier = y => x => x * y;const multiplyBy3 = multiplyCurrier(3);multiplyBy3(5);// 15const multiplyBy5 = multiplyCurrier(5);multiplyBy5(5);// 25const multiplyBy7 = multiplyCurrier(7);multiplyBy7(5);// 35
If you have a curried function with multiple arguments like this, which lets you create functions to grab substrings:
const curriedSubstring = start => length => string =>str.substr(start, length);
You can pass multiple arguments at once, to avoid making an unneeded function along the way. Simply add extra pairs of parenthesis with arguments onto the function call.
const getFirstChar = string => curriedSubstring(0)(1);getFirstChar('potatoes');// 'p'
A more understandable syntax for making curried functions can be done with a
compose function like this:
const compose = (...fns) =>fns.reduce((f, g) => (...args) => f(g(...args)));
With this, you first pass in the currier function and then all the arguments you want to give it. So to make the
getFirstChar function above, you could do this:
const getFirstChar = compose(curriedSubstring, 0 , 1);getFirstChar('carrots');// 'c'
As shown above, currying lets you make different variations of functions with less repetition. This comes in handy for functions that have three or more arguments to customize. Any times you see multiple functions with any kind of foundational logic, there may be a chance to use currying for a more elegant, less repetitive version.