Так что карри?

Проще говоря, каррирование - это способ изменения функции, которая принимает несколько аргументов (n) за раз, на функцию, которая принимает меньшие аргументы за раз и возвращает функцию для принятия оставшихся аргументов, которая снова возвращает другую функцию, и так до тех пор, пока все аргументы передаются и, наконец, возвращает результат.

Начнем с простого примера каррирования.

let multiply = (a, b) => a*b;

Вышеупомянутая функция умножить принимает два ввода одновременно. Карри-версия этой функции будет -

let multiplyCurried = (a) => (b) => a*b; 
let multiplyTo2 = multiplyCurried(2);
console.log(multiplyTo2(3)); // 6
console.log(multiplyTo2(4)); // 8

Теперь давайте рассмотрим некоторые из сложных вопросов, которые обычно задают в интервью по каррированию.

Вопрос 1 интервью

Итак, как написать функцию-оболочку curry, которая принимает функцию, скажем, func, и возвращает каррированную версию func.

// Let's pass a function func as input.
// So to get the curried version of func, first thing we should do is return a function which takes arguments. In our case we are returning curried.
// Now in curried we need to check the length of arguments that are passed to it. If all the arguments are passed we call func else we need to again return a function to get the remaining arguments and so on until all the arguments are passed.
// So we can see a recursive behavior here. So how do we achieve this?
// We call curried recursively until all the arguments are received.

Ниже приведен код: -

function curry(func) {
    function curried(...args) {
        if(args.length >= func.length) {
            return func(...args);
        } else {
            return function(...more) {
                return curried(...args,...more);
            }
        }
    }
    return curried;
}

Теперь, когда мы написали нашу функцию карри, давайте протестируем ее.

function multiply(a, b, c) {
    return a*b*c;
}
// To get the curried version of multiply we pass it to our above curry function.
let curried = curry(multiply);
console.log(curried(2)(3)(4)); // 24
console.log(curried(2,3)(4));  // 24
console.log(curried(2,3,4));  // 24
console.log(curried(5)(6,7)); // 210

Вопрос 2 интервью

sum (1) (2) (3)… (n) - очень распространенный вопрос, в котором используется указанная выше концепция и который также может быть решен аналогично указанному выше решению.

// We are doing a small tweak here, we are overwriting the toString method of the sum function to return the total. 
function sum(...args) {
    function inner(...more) {
        return sum(...args,...more);
    }
    let total = args.reduce((a, b) => a+b, 0); 
    inner.toString = () => total; 
    
    return inner;
}
console.log(sum(1)(2)(2)(3)) // 8
console.log(sum(1,2)(2,3)) //8

Ссылка stackblitz для приведенных выше примеров.