Каррированные функции

Каррирование — это преобразование функции, которая принимает несколько аргументов, в последовательность функций, каждая из которых принимает ровно один аргумент.

Результат — функция, которую можно вызывать по частям, сохраняя промежуточные состояния через замыкания.

Пример:

function multiply(a) {
  return function(b) {
    return function(c) {
      return a * b * c;
    };
  };
}

const result = multiply(2)(5)(3); // 30

Здесь:

  • multiply(2) возвращает функцию, запоминающую a = 2
  • multiply(2)(5) возвращает функцию, запоминающую a = 2 и b = 5
  • multiply(2)(5)(3) возвращает результат: 2 * 5 * 3 = 30

Каждый уровень — это новая функция, которая замыкает на переменные внешнего уровня.

Почему это полезно

Каррирование позволяет создавать переиспользуемые частичные версии функций:

function greet(greeting, name) {
  return `${greeting}, ${name}!`;
}

function curry(fn) {
  return function(a) {
    return function(b) {
      return fn(a, b);
    };
  };
}

const greetWith = curry(greet);
const sayHello = greetWith("Привет");

console.log(sayHello("Анна")); // "Привет, Анна!"
console.log(sayHello("Иван")); // "Привет, Иван!"

Теперь sayHello — это готовая функция, которая всегда использует "Привет". Её можно передавать как колбэк, использовать в массивах:

const users = ["Анна", "Иван", "Мария"];
const greetings = users.map(sayHello);
// ["Привет, Анна!", "Привет, Иван!", "Привет, Мария!"]

В реальных сценариях

  • Форматирование данных: formatDate(locale, format) → formatDateRu = curry(formatDate)("ru-RU")
  • Валидация: validateLength(min, max, value) → validateMin5 = curry(validateLength)(5, 100)
  • Настройка запросов: apiRequest(method, url, headers) → get = curry(apiRequest)("GET")

Каррирование — не синтаксическая фича JavaScript, а паттерн, основанный на замыканиях.
Он особенно полезен в функциональном стиле программирования и для создания гибких, переиспользуемых утилит.
Используйте его, когда нужно создавать специализированные версии функций с предустановленными параметрами.