Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

3 Композиция и суперпозиция функций в функциональном программировани кратко

Лекция



Привет, Вы узнаете о том , что такое 3 Композиция и суперпозиция функций в функциональном программировани, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое 3 Композиция и суперпозиция функций в функциональном программировани , настоятельно рекомендую прочитать все из категории Функциональное программирование.

Композиция и суперпозиция функций

3 Композиция и суперпозиция функций в функциональном программировани

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

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

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

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

В функциональном программировании функции — наши строительные блоки. Мы пишем их для решения определенных задач, а потом складываем вместе, как блоки в Lego™.

Результат такого сложения называется композицией функций.

Так как же это работает? Давайте начнем с двух JavaScript-функций:

var add10 = function(value) {
    return value + 10;
};
var mult5 = function(value) {
    return value * 5;
};

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

var add10 = value => value + 10;
var mult5 = value => value * 5;

Так-то лучше. Теперь давайте представим, что нам нужна функция, принимающая значение и добавляющая к нему 10, после чего умножающая результат на 5. Мы могли бы написать:

var mult5AfterAdd10 = value => 5 * (value + 10)

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

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

Так что вместо этого давайте используем add10 и mult5 и соберем новую функцию:

var mult5AfterAdd10 = value => mult5(add10(value));

Мы просто использовали существующие функции, чтобы получить mult5AfterAdd10, но есть и способ получше.

В математике f ∘ g — композиция функций (прим. Об этом говорит сайт https://intellect.icu . пер., или суперпозиция функций) и читается она как «применение функции f к результату функции g» или более просто «выполнение f после g». Получается, что (f ∘ g)(x) — эквивалент вызова функции f после функции g со значением x или еще проще: f(g(x)).

В нашем примере у нас mult5 ∘ add10 или «mult5 после add10», отсюда и название нашей функции mult5AfterAdd10.

И это объясняет то, что мы сделали. Мы вызвали mult5 после вызова add10 с value или просто: mult5(add10(value)).

Поскольку JavaScript нативно не реализует возможность композиции функций, давайте взглянем на Elm:

add10 value =
    value + 10mult5 value =
    value * 5mult5AfterAdd10 value =
    (mult5 << add10) value

В Elm функции компонуются с помощью инфиксального оператора <<. Это дает нам визуально понять как параметры из одной функции «перетекают» в другую. Сначала value попадает в add10, а затем ее результат попадает в mult5.

Обратите внимание на скобки в mult5AfterAdd10, то есть именно на выражение (mult5 << add10). Они там затем, чтобы быть уверенными, что value будет передана внутрь выражения после того, как функции в нем скомпонуются.

Вы можете скомпоновать столько функций, сколько захотите, например:

f x =
   (g << h << s << r << t) x

В этом случае x передается в t, чей результат передается в r, чей результат, в свою очередь, — в s и так далее. Если вы захотите сделать что-то подобное в JavaScript, это будет выглядеть примерно так: g(h(s(r(t(x))))) — просто какой-то ад из круглых скобок.

Бесточечная нотация функций

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

Вы заметите, что в mult5AfterAdd10 значение value определяется дважды. Один раз в списке параметров и один раз в момент использования.

-- Эта функция ожидает 1 входной параметрmult5AfterAdd10 value =
    (mult5 << add10) value

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

-- Эта функция тоже ожидает 1 входной параметрmult5AfterAdd10 =
    (mult5 << add10)

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

Во-первых, нам не нужно определять лишние параметры. И поскольку мы их не определяем, нам также не нужно придумывать им имена.

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

Особенности безточесных функций

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

Теперь давайте попробуем использовать эти идеи при слегка ином сценарии и посмотрим, насколько они ему соответствуют. Представьте, что мы заменяем add10 на add:

add x y =
    x + ymult5 value =
    value * 5

Как нам создать mult5AfterAdd10, используя эти две функции?

Ладно, если вы действительно потратите время, раздумывая над этим вопросом, то вернетесь примерно с таким решением:

-- Это неверно !!!!mult5AfterAdd10 =
    (mult5 << add) 10

Но такой код не будет работать. Потому что add принимает два параметра.

Если это не так очевидно в Elm, попробуйте написать то же самое в JavaScript:

var mult5AfterAdd10 = mult5(add(10)); // не работает

Этот код неверен, но почему?

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

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

Давайте попробуем еще раз:

var mult5AfterAdd10 = y => mult5(add(10, y)); // не бесточечный стиль

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

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

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

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

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

Из статьи мы узнали кратко, но содержательно про
создано: 2020-08-12
обновлено: 2024-11-14
14



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Функциональное программирование

Термины: Функциональное программирование