The act of currying can be described as taking a multivariate function and turning it into a series of unary functions.
Let's see an example:
const add = a => b=> a + b; const inc = add(1); const res = inc(3) // 4
This is a very basic currying example.
We wrote a function 'add' take a param 'a' return a function which take param 'b', finally return a + b;
We can based on 'add' function to create another function 'inc'. This approach is good for resuability. But there is one problem, because you cannot do:
add(1,3)
To solve the problem we need to write a 'curry' function, the basic idea is:
1. Check the passed in function, how many params it should takes, in our case 'add' function take 2 params.
2. 'curry' should return another function, inside function it should check, if length of params is the same as function's params, in our case is:
add(1,3)
Then we invoke function immediately. (Using .call for immediately invoke)
3. Otherwise, we should still return a function with param partially applyied. (using .bind for partially apply)
function curry(fn) { // The number of fn's params // fn = (a, b) => a + b // then length is 2 const arity = fn.length; console.log(arity) return function $curry(...args) { console.log(args, args.length) if (args.length < arity) { // partially apply // in case of add(1)(2) return $curry.bind(null, ...args); } // immediately invoke // in case of add(1,2) return fn.call(null, ...args); }; }; const add = curry((a, b) => a + b); const inc = add(1); const res = inc(2) // 3
Arity describes the number of arguments a function receives. Depending on the number it receives, there are specific words to describe these functions.
A function that receives one is called a unary function.
A function that receives two arguments is called a binary,
three equals a ternary,
and four equals a quaternary,
so forth and so on.