Что такое каррирование js

Каррирование

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

Каррирование не вызывает функцию. Оно просто трансформирует её.

Давайте сначала посмотрим на пример, чтобы лучше понять, о чём речь, а потом на практическое применение каррирования.

Как вы видите, реализация довольна проста: это две обёртки.

Более продвинутые реализации каррирования, как например _.curry из библиотеки lodash, возвращают обёртку, которая позволяет запустить функцию как обычным образом, так и частично.

Каррирование? Зачем?

Чтобы понять пользу от каррирования, нам определённо нужен пример из реальной жизни.

А теперь давайте применим к ней каррирование!

После этого log продолжает работать нормально:

…Но также работает вариант с каррированием:

Давайте сделаем удобную функцию для логов с текущим временем:

Теперь logNow – это log с фиксированным первым аргументом, иначе говоря, «частично применённая» или «частичная» функция.

Мы можем пойти дальше и сделать удобную функцию для именно отладочных логов с текущим временем:

Продвинутая реализация каррирования

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

Она очень короткая:

Новое curry выглядит сложновато, но на самом деле его легко понять.

Когда мы запускаем её, есть две ветви выполнения if :

Для вызова curried(1)(2)(3) :

Если всё ещё не понятно, просто распишите последовательность вызовов на бумаге.

Для каррирования необходима функция с фиксированным количеством аргументов.

Но, как было описано, большинство реализаций каррирования в JavaScript более продвинуты: они также оставляют вариант вызова функции с несколькими аргументами.

Итого

Источник

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

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

Принципы функционального программирования поддерживает множество языков. Среди них можно отметить JavaScript, Haskell, Clojure, Erlang. Использование механизмов функционального программирование подразумевает знание, кроме прочих, таких концепций, как чистые функции, каррирование функций, функции высшего порядка.

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование?

Каррирование или карринг (currying) в функциональном программирование — это преобразование функции с множеством аргументов в набор вложенных функций с одним аргументом. При вызове каррированной функции с передачей ей одного аргумента, она возвращает новую функцию, которая ожидает поступления следующего аргумента. Новые функции, ожидающие следующего аргумента, возвращаются при каждом вызове каррированной функции — до тех пор, пока функция не получит все необходимые ей аргументы. Ранее полученные аргументы, благодаря механизму замыканий, ждут того момента, когда функция получит всё, что ей нужно для выполнения вычислений. После получения последнего аргумента функция выполняет вычисления и возвращает результат.

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

Арность — это количество аргументов функции. Например — вот объявление пары функций:

Функция fn принимает два аргумента (это бинарная или 2-арная функция), функция _fn принимает три аргумента (тернарная, 3-арная функция).

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

Рассмотрим пример. У нас имеется следующая функция:

Она принимает три аргумента и возвращает их произведение:

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

Оказывается, что одна функция превратилась в несколько функций. При использовании новой конструкции каждая функция, кроме последней, возвращающей результат вычислений, принимает аргумент и возвращает другую функцию, также способную принять аргумент и возвратить другую функцию. Если конструкция вида multiply(1)(2)(3) кажется вам не слишком понятной, давайте, чтобы лучше в этом разобраться, распишем её в таком виде:

Теперь построчно разберём то, что здесь происходит.

Сначала мы передаём аргумент 1 функции multiply :

При работе этой функции срабатывает такая конструкция:

В результате этого вызова выполнится следующий код:

Константа mul2 будет содержать ссылку на функцию, которая могла бы оказаться в ней, например, в результате выполнения следующей операции:

Результатом этих вычислений будет 6 :

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

Вот как выглядит её каррированный вариант:

Итак, каррирование базируется на следующей идее: на основе некоей функции создают другую функцию, которая возвращает специализированную функцию.

Каррирование и частичное применение функций

Сейчас, возможно, возникает ощущение, что количество вложенных функций, при представлении функции в виде набора вложенных функций, зависит от количества аргументов функции. И, если речь идёт о каррировании, то это так.

Особый вариант функции для вычисления объёма, которую мы уже видели, можно сделать и таким:

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

Та функция, которая получилась после вызова volume(70) реализует концепцию частичного применения функции (partial function application). Каррирование и частичное применение функций очень похожи друг на друга, но концепции это разные.

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

Например, имеется такая функция:

Её можно преобразовать в такую:

Реализация функции performOp() здесь не приводится, так как она на рассматриваемые концепции не влияет.

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

Каррированный вариант функции будет выглядеть так:

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

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

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

Точно так же будет выглядеть и результат её каррирования.

О практическом применении концепций каррирования и частичного применения функций

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

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

Несложно заметить, что нам, при таком подходе, постоянно придётся вызывать эту функцию с двумя аргументами:

Исходную функцию можно привести к такому виду, который позволял бы получать новые функции с заранее заданным уровнем скидки, при вызове которых им достаточно передавать сумму покупки. Функция discount() в нашем примере имеет два аргумента. Вот как выглядит то, во что мы её преобразуем:

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

Теперь функцию twentyPercentDiscount() можно вызывать для расчёта стоимости товаров с учётом скидки в 20%:

Универсальная функция для частичного применения других функций

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

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

Итоги

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

Уважаемые читатели! Пользуетесь ли вы техниками каррирования и частичного применения функций в своих проектах?

Источник

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

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

Принципы функционального программирования поддерживает множество языков. Среди них можно отметить JavaScript, Haskell, Clojure, Erlang. Использование механизмов функционального программирование подразумевает знание, кроме прочих, таких концепций, как чистые функции, каррирование функций, функции высшего порядка.

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование?

Каррирование или карринг (currying) в функциональном программирование — это преобразование функции с множеством аргументов в набор вложенных функций с одним аргументом. При вызове каррированной функции с передачей ей одного аргумента, она возвращает новую функцию, которая ожидает поступления следующего аргумента. Новые функции, ожидающие следующего аргумента, возвращаются при каждом вызове каррированной функции — до тех пор, пока функция не получит все необходимые ей аргументы. Ранее полученные аргументы, благодаря механизму замыканий, ждут того момента, когда функция получит всё, что ей нужно для выполнения вычислений. После получения последнего аргумента функция выполняет вычисления и возвращает результат.

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

Арность — это количество аргументов функции. Например — вот объявление пары функций:

Функция fn принимает два аргумента (это бинарная или 2-арная функция), функция _fn принимает три аргумента (тернарная, 3-арная функция).

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

Рассмотрим пример. У нас имеется следующая функция:

Она принимает три аргумента и возвращает их произведение:

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

Оказывается, что одна функция превратилась в несколько функций. При использовании новой конструкции каждая функция, кроме последней, возвращающей результат вычислений, принимает аргумент и возвращает другую функцию, также способную принять аргумент и возвратить другую функцию. Если конструкция вида multiply(1)(2)(3) кажется вам не слишком понятной, давайте, чтобы лучше в этом разобраться, распишем её в таком виде:

Теперь построчно разберём то, что здесь происходит.

Сначала мы передаём аргумент 1 функции multiply :

При работе этой функции срабатывает такая конструкция:

В результате этого вызова выполнится следующий код:

Константа mul2 будет содержать ссылку на функцию, которая могла бы оказаться в ней, например, в результате выполнения следующей операции:

Результатом этих вычислений будет 6 :

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

Вот как выглядит её каррированный вариант:

Итак, каррирование базируется на следующей идее: на основе некоей функции создают другую функцию, которая возвращает специализированную функцию.

Каррирование и частичное применение функций

Сейчас, возможно, возникает ощущение, что количество вложенных функций, при представлении функции в виде набора вложенных функций, зависит от количества аргументов функции. И, если речь идёт о каррировании, то это так.

Особый вариант функции для вычисления объёма, которую мы уже видели, можно сделать и таким:

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

Та функция, которая получилась после вызова volume(70) реализует концепцию частичного применения функции (partial function application). Каррирование и частичное применение функций очень похожи друг на друга, но концепции это разные.

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

Например, имеется такая функция:

Её можно преобразовать в такую:

Реализация функции performOp() здесь не приводится, так как она на рассматриваемые концепции не влияет.

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

Каррированный вариант функции будет выглядеть так:

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

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

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

Точно так же будет выглядеть и результат её каррирования.

О практическом применении концепций каррирования и частичного применения функций

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

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

Несложно заметить, что нам, при таком подходе, постоянно придётся вызывать эту функцию с двумя аргументами:

Исходную функцию можно привести к такому виду, который позволял бы получать новые функции с заранее заданным уровнем скидки, при вызове которых им достаточно передавать сумму покупки. Функция discount() в нашем примере имеет два аргумента. Вот как выглядит то, во что мы её преобразуем:

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

Теперь функцию twentyPercentDiscount() можно вызывать для расчёта стоимости товаров с учётом скидки в 20%:

Универсальная функция для частичного применения других функций

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

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

Итоги

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

Уважаемые читатели! Пользуетесь ли вы техниками каррирования и частичного применения функций в своих проектах?

Источник

Что такое каррирование js

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

Что такое каррирование функций?

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

В самом простом случае, если у нас есть функция вида:

(a, b) => a + b

каррированная будет такой:

(a) => (b) => a + b

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

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

Зачем нужно каррирование?

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

Допустим у нас есть некий список объектов, нужно создать функцию для получения из каждого элемента списка некого свойства.

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

Выглядит вполне обычно, думаю ни для кого не в новинку такой код — все так писали или пишут.

А теперь давайте посмотрим как можно сделать его лучше, используя карринг функций 😉.

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

Ничего особенного — просто каррированный геттер для свойств объекта и каррированная версия метода map.

Используя эти функции наш код становится куда более лаконичным:

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

Благодаря этой особенности, вместо описания конретной логики работы с конкретными данными, как это обычно происходит при имеративном подходе — мы пишем рецепты путём комбинирования функций.

При работе с этой библиотекой мы думаем не о конкретных данных, а об алгоритме функции. Вот простой пример:

Разберём что тут происходит:

Мы написали рабочую функцию, но при этом нигде не описывали ни получаемые аргументы, ни то куда и как их применить, мы просто описали рецепт обработки данных.

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

В чём плюсы карринга?

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

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

Используя карринг и композицию вы можете строить сложную логику с помощью простых функций.

Пример из жизни

В бэкенде сервиса Мозаика.ЕДА мы активно используем композицию каррированных функций для удобного расширения поведения ручек GraphQL.

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

Источник

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Принципы функционального программирования поддерживает множество языков. Среди них можно отметить JavaScript, Haskell, Clojure, Erlang. Использование механизмов функционального программирование подразумевает знание, кроме прочих, таких концепций, как чистые функции, каррирование функций, функции высшего порядка.

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

Что такое каррирование?

Каррирование или карринг (currying) в функциональном программирование — это преобразование функции с множеством аргументов в набор вложенных функций с одним аргументом. При вызове каррированной функции с передачей ей одного аргумента, она возвращает новую функцию, которая ожидает поступления следующего аргумента. Новые функции, ожидающие следующего аргумента, возвращаются при каждом вызове каррированной функции — до тех пор, пока функция не получит все необходимые ей аргументы. Ранее полученные аргументы, благодаря механизму замыканий, ждут того момента, когда функция получит всё, что ей нужно для выполнения вычислений. После получения последнего аргумента функция выполняет вычисления и возвращает результат.

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

Арность — это количество аргументов функции. Например — вот объявление пары функций:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Функция fn принимает два аргумента (это бинарная или 2-арная функция), функция _fn принимает три аргумента (тернарная, 3-арная функция).

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

Рассмотрим пример. У нас имеется следующая функция:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Она принимает три аргумента и возвращает их произведение:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Оказывается, что одна функция превратилась в несколько функций. При использовании новой конструкции каждая функция, кроме последней, возвращающей результат вычислений, принимает аргумент и возвращает другую функцию, также способную принять аргумент и возвратить другую функцию. Если конструкция вида multiply(1)(2)(3) кажется вам не слишком понятной, давайте, чтобы лучше в этом разобраться, распишем её в таком виде:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Теперь построчно разберём то, что здесь происходит.

Сначала мы передаём аргумент 1 функции multiply :

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

При работе этой функции срабатывает такая конструкция:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

В результате этого вызова выполнится следующий код:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Константа mul2 будет содержать ссылку на функцию, которая могла бы оказаться в ней, например, в результате выполнения следующей операции:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Результатом этих вычислений будет 6 :

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Вот как выглядит её каррированный вариант:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Итак, каррирование базируется на следующей идее: на основе некоей функции создают другую функцию, которая возвращает специализированную функцию.

Каррирование и частичное применение функций

Сейчас, возможно, возникает ощущение, что количество вложенных функций, при представлении функции в виде набора вложенных функций, зависит от количества аргументов функции. И, если речь идёт о каррировании, то это так.

Особый вариант функции для вычисления объёма, которую мы уже видели, можно сделать и таким:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Та функция, которая получилась после вызова volume(70) реализует концепцию частичного применения функции (partial function application). Каррирование и частичное применение функций очень похожи друг на друга, но концепции это разные.

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

Например, имеется такая функция:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Её можно преобразовать в такую:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Реализация функции performOp() здесь не приводится, так как она на рассматриваемые концепции не влияет.

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

Каррированный вариант функции будет выглядеть так:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Точно так же будет выглядеть и результат её каррирования.

О практическом применении концепций каррирования и частичного применения функций

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

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Несложно заметить, что нам, при таком подходе, постоянно придётся вызывать эту функцию с двумя аргументами:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Исходную функцию можно привести к такому виду, который позволял бы получать новые функции с заранее заданным уровнем скидки, при вызове которых им достаточно передавать сумму покупки. Функция discount() в нашем примере имеет два аргумента. Вот как выглядит то, во что мы её преобразуем:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Теперь функцию twentyPercentDiscount() можно вызывать для расчёта стоимости товаров с учётом скидки в 20%:

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Универсальная функция для частичного применения других функций

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

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Что такое каррирование js. Смотреть фото Что такое каррирование js. Смотреть картинку Что такое каррирование js. Картинка про Что такое каррирование js. Фото Что такое каррирование js

Итоги

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *