https://bigfrontend.dev/problem/implement-curry
Currying is a useful technique used in JavaScript applications.
Please implement a curry() function, which accepts a function and return a curried one.
Here is an example
# Example 1
const join = (a, b, c) => {
return `${a}_${b}_${c}`;
};
const curriedJoin = curry(join);
curriedJoin(1, 2, 3); // '1_2_3'
curriedJoin(1)(2, 3); // '1_2_3'
curriedJoin(1, 2)(3); // '1_2_3'
# Example 2
function sum(a, b, c) {
return a + b + c;
}
let curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // Outputs: 6
console.log(curriedSum(1, 2)(3)); // Outputs: 6
console.log(curriedSum(1, 2, 3)); // Outputs: 6
more to read
https://javascript.info/currying-partials https://lodash.com/docs/4.17.15#curry
/**
* @param { Function } func
*/
function curry(func) {
// Return a wrapper function to make it curry-able.
return function curried(...args) {
// If passed arguments count is greater than or equal to original function 'func'
// parameters count, directly call 'func' with passed arguments.
if (args.length >= func.length) {
return func.apply(this, args);
} else {
// Otherwise return another wrapper function to gather new argument
// and pass it to `curried` function. This will continue until
// arguments count >= parameters count.
return function (...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}
the function curry in the provided JavaScript code is a higher-order function that transforms a given function into a curried function.
A curried function is a function that takes multiple arguments one at a time. Given a function with 3 parameters, the curried version will take one argument and return a function that takes the next argument, which returns a function that takes the third argument. The last function returns the result of applying the function to all of its arguments.
Here's a step-by-step explanation of the code:
- The curry function takes a function func as an argument.
- It returns a new function curried that can be called with some arguments (...args).
- When curried is invoked, it checks if the number of arguments provided is enough to invoke the original function func. This is done by comparing args.length with func.length, where func.length is the number of expected parameters of func.
- If enough arguments are provided, it calls func with the provided arguments using func.apply(this, args).
- If not enough arguments are provided, it returns a new function that expects the remaining arguments. This function, when called, will call curried with the old and new argument.
Here's an example:
function sum(a, b, c) {
return a + b + c;
}
let curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // Outputs: 6
In this example, curriedSum is a curried version of sum. When we call curriedSum(1)(2)(3), it's equivalent to calling sum(1, 2, 3). Each call to curriedSum returns a new function expecting the next argument until all arguments are provided.
let's break down how the curry function works with sum under the hood:
let curriedSum = curry(sum);
Here, curry is called with sum as an argument. curry returns a new function curried that can be called with some arguments. This returned function is stored in curriedSum.
console.log(curriedSum(1)(2)(3))
Here's what happens step by step:
-
curriedSum(1) is called. Inside curried, args is an array with one element [1]. Since args.length (1) is less than func.length (3, because sum takes 3 arguments), curried returns a new function that takes the remaining arguments.
-
This returned function is immediately called with (2). Now args is [1, 2]. Again, args.length (2) is less than func.length (3), so curried returns another function.
-
This returned function is immediately called with (3). Now args is [1, 2, 3]. This time, args.length (3) is equal to func.length (3), so curried calls sum with these arguments using func.apply(this, args), which is equivalent to sum(1, 2, 3). This returns 6, which is then logged to the console.
The other calls
console.log(curriedSum(1, 2)(3))
console.log(curriedSum(1, 2, 3))
work in a similar way. The difference is that more arguments are provided at once, so the curried function returns a function that takes the remaining arguments fewer times before it has enough arguments to call sum.