Краткое руководство

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

Краткий пример этого:

let arr = Array(5);
function getLength(array) { 
  return array.length; 
};
function showLength(length) { 
  alert(length);
};
showLength( getLength( arr ) ); // alerts 5
  • getLength процессы arr
  • getLength возвращает значение length в showLength
  • showLength показывает значение с помощью alert.

Как вы могли заметить, приведенный выше пример действительно бесполезен. Важна концепция. Для тех, кто знаком с историей США, часть промышленной революции была вызвана взаимозаменяемыми деталями. Идея взаимозаменяемых частей означает, что если вы покупаете лампу накаливания от компании A и решаете, что спустя годы вы хотите заменить ее люминесцентной лампой от компании B Переделывать проводку светильника не нужно. Обе лампочки подходят к резьбе и принимают стандартное напряжение.

В предыдущем примере я использовал предупреждение для создания всплывающего окна на экране. Что, если через несколько недель после создания этого приложения я больше не хочу, чтобы всплывающее окно для этой конкретной страницы, а вместо этого я хочу записывать информацию в консоль? Я мог бы изменить код функции showLength, но если бы я использовал эту функцию где-нибудь еще, это могло бы сломать другие части приложения. Именно здесь проявляется красота функциональной композиции. Вместо того, чтобы нарушать работу приложения или создавать условный оператор для управления тем, должна ли информация быть предупреждена или регистрироваться, я могу написать новую функцию и легко заменить имя вызываемой функции:

let arr = Array(5);
function getLength(array) { 
  return array.length; 
};
function showLength(length) { 
  alert(length);
};
function logLength(length) {
 console.log(length);
};
logLength( getLength( arr ) ); // logs 5;

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

Каррирование против частичных приложений

Каррирование и частичное приложение - очень похожие концепции, и их часто путают друг с другом. Почему? Ну, потому что код, который производит то и другое, почти идентичен, и даже опытные разработчики будут злоупотреблять этими терминами настолько часто, что они становятся почти синонимами. К тому же определение, которое вы, вероятно, найдете для описания различий, как и многие другие объяснения в информатике, чрезвычайно многословно:

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

Таким образом, любое частичное приложение можно свести к одной операции карри. Таким образом, карри более подходящим образом определяется как операция, которая во многих теоретических случаях часто применяется рекурсивно, но теоретически неотличима (если рассматривать ее как операцию) от частичного приложения.

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

(со ссылкой на WikiPedia)

Поначалу это немного обезоруживает. Ненавижу это говорить, но вы привыкаете к длинным, запутанным и, казалось бы, нелепым предложениям, когда достаточно долго работаете в любой области технологий. Как всегда, я бы солгал, если бы сказал, что не испытываю презрения к практике делать простые концепции непонятными для непрофессионала. Человек, пытающийся понять концепцию, не должен искать отрывки из того, что он читает, и самостоятельно соединять их воедино - это должно быть изложено как можно яснее Учителем.

Человеку, пытающемуся понять концепцию, не нужно искать отрывки из того, что они читают, и самостоятельно соединять их - Учитель должен изложить это как можно яснее.

Без лишних слов мы собираемся создать простую функцию добавления, чтобы быстро изучить концепции каррирования и частичного применения и их различий. Давайте взглянем!

Обычная функция сложения

function addition(x, y) {
 return x + y;
}
addition(5, 6); // 11

Надеемся, что указанная выше функция очень проста для чтения. Для ясности представим пьесу по пьесе:

  • Мы объявляем функцию с именем addition
  • У функции есть два параметра, которые она принимает. Они названы x и y..
  • Когда функции передаются два параметра, мы return добавляем два параметра (x и y) вместе.
  • Мы показываем пример вызова функции с параметрами 5 и 6. В результате возвращается значение 11.

Как бы это выглядело, если бы мы написали это как функцию каррирования? Давайте посмотрим на завершенную функцию, а затем быстро объясним.

Функция сложения каррирования:

function currying_addition(x) {
  return function(y) {
   return x + y;
  }
}
currying_addition(5)(6); // 11

Вышеизложенное поначалу может сбивать с толку. Бывает, но не беспокойтесь! Я проведу вас через это!

  • Мы объявляем функцию с именем currying_addition
  • Наша currying_addition функция принимает один параметр, x
  • Мы немедленно возвращаем анонимную функцию (анонимная функция - это объявление функции без имени)
  • Анонимная функция принимает один параметр, y
  • Анонимная функция возвращает значение x + y
  • Мы выполняем вызов currying_addition с параметром 5, а затем вызываем возвращенную функцию с помощью параметра 6 - это возвращает 11

Что важно знать о каррировании (и если у вас есть зоркий глаз, вы, возможно, уже это заметили), для каждого вызова функции требуется только один параметр. Говоря техническим языком, все они являются унарными функциями (унарные - это простой способ сказать один, и когда мы говорим о функции, мы имеем в виду количество параметров).

Примечание. Во время программирования вы, возможно, слышали термины двоичный или троичный - все они имеют разные значения в зависимости от того, что мы имеем в виду, но если вы видите слово двоичный, вы знаете, что есть два чего-то, если вы читаете троичный, вы знаете что есть три чего-то. Эти дескрипторы называются числовой нотацией, и когда мы применяем их к функциям (унарная функция, двоичная функция, троичная функция), мы имеем в виду количество параметров, которые принимает функция. . Если количество параметров не задано, функция описывается как полиадическая или, чаще, как вариативная.

Другой способ указать количество параметров функции - просто указать, что она имеет Арность, равную 1, или Арность, равную 2, или Арность из 3 и т. д. Арность - это термин, который напрямую коррелирует с количеством параметров, поэтому, если вы говорите «Рафаэль, эта функция имеет арность из 1! »или« Рафаэль, это унарная функция! »вы говорите то же самое, если не считать напыщенности.

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

Примечание. В каррировании часто используется Рекурсия -. Для получения дополнительной информации прочтите мою статью Общие сведения о рекурсии в JavaScript.

Ладно, это карри! Если вы все еще немного запутались, я опубликую несколько справочных статей в разделе Ресурсы, которые вы можете просмотреть. (кстати, я НАСТОЯТЕЛЬНО рекомендую семинар Дугласа Крокфорда в рамках Front End Masters. Это фантастика!) Не волнуйтесь, если поначалу будет сложно понять его. Иногда концепции нужно время, чтобы «щелкнуть», но как только они это сделают, они станут бесценными!

Так как же будет выглядеть функция сложения при использовании частичного приложения? Давайте посмотрим!

Частичная функция приложения:

function add(x, y) {
 return x + y;
}
function partial_application(y) {
  return add(3, y);
}
partial_application(8); // 11

Пошаговая инструкция:

  • Мы объявляем функцию с именем add
  • У функции есть два параметра, которые она принимает. Они названы x и y..
  • Когда функции передаются два параметра, мы return суммируем два параметра (x и y).
  • Мы объявляем функцию с именем partial_application
  • partial_application имеет единственный параметр. Этот параметр называется y.
  • Функция вызывает и возвращает функцию add с 3 в качестве первого параметра и y в качестве второго.
  • Например, partial_application вызывается с параметром 8 и возвращает значение 11

Это может быть немного более запутанным, чем наш предыдущий пример, по той простой причине, что здесь больше частей, хотя я обещаю, что это не так сложно, как может показаться. Мы устанавливаем add функцию и partial_application функцию. Функция partial_application вызывает add с параметром 3 и параметром y. Единственная задача функции - вернуть значение из частично примененной add функции.

Позвольте мне повторить, поскольку я считаю, что это самое большое препятствие на пути к пониманию частичного применения. Эта концепция означает частичное применение. Это кажется очевидным, но в области технологий слово Применение явно имеет альтернативное значение, и когда вы впервые встретите этот термин, вас простят за то, что вы инстинктивно придали этому слову неправильное значение.

Мы должны взглянуть на это следующим образом: допустим, Хьюго работает в бассейне, нанося людям лосьон для загара (, вероятно, это работа). Придя на работу, он обнаруживает, что человек предыдущей смены, настоящий псих по имени Ленни, наносил лосьон только на левую сторону всех загорающих. В шоке от отсутствия симметрии Хьюго поспешно наносит лосьон для загара на правую сторону всех загорающих, чтобы убедиться, что они полностью покрыты.

В этом примере Хьюго - это функция partial_application, а Ленни - функция add в функции partial_application. Ленни уже сделал половину каждого человека, но ни один из них не был задействован полностью, пока Хьюго не приступил к работе и не закончил работу.

В приведенном выше примере кода функцияadd имеет значение3pre, примененное нашей функцией partial_application, и хотя она принимает только один параметр (унарная функция явно не привязана к currying), поскольку он принимает этот параметр и использует его вместе с уже частично примененной функцией add, мы считаем это частичным применением.

Ресурсы