Сделайте функцию, которая поддерживает каррирование и традиционные множественные параметры


Вопрос: Как бы вы это сделали?
добавить(2)(5); // 7
добавить(2, 5); // 7

Я пытаюсь решить вопрос выше: Я знаю, что первое решение использует карринг и будет реализовано следующим образом:

var add = functoin(x){
return function (y){
return x+y;
};
};

В то время как вторая-это ваша нормальная функция:

var add = functoin(x,y){
return x+y;
};
Есть ли способ заставить работать и то и другое одновременно?
2 4

2 ответа:

Вы можете использовать функцию более высокого порядка, чтобы обернуть другие функции с таким поведением.

Этот вид функции часто называютcurry, и он поставляется со многими библиотеками (lodash , например).

curry возвращает новую функцию, которая проверяет, все ли ожидаемые аргументы были предоставлены. Если они есть, он вызывает originalFunction. Если нет, то он возвращает частично примененную функцию,

Эта реализация использует Function#length чтобы проверить вызов arity, так что он работает с любым номером из аргументов.

function curry (fn) {
  return function (...args) {
    if (args.length >= fn.length) {
      return fn.call(this, ...args)
    } else {
      return curry(fn.bind(this, ...args))
    }
  }
}

function add (x, y) {
  return x + y;
}

// You can curry any function!
const curriedAdd = curry(add);

console.log(curriedAdd(1, 2)); // 3
console.log(curriedAdd(1)(2)); // 3
console.log(curriedAdd(1));    // a function

Вы можете проверить количество передаваемых аргументов и вернуть один или оба в зависимости от этого:

function add(a, b) {
  if (arguments.length == 2) {
    return a + b;
  }
  return function(b) {
    return add(a, b);
  }
}

console.log(add(2)(5)); // 7
console.log(add(2, 5)); // 7