Композиция функций с несколькими параметрами
Ну а как насчёт функций, которые принимают несколько параметров? Если мы хотим использовать их в композиции, обычно мы частично применяем их до тех пор, пока не получим функцию, принимающую только один параметр. Запись
>sum (replicate 5 (max 6.7 8.9))
может быть преобразована так:
>(sum . replicate 5) (max 6.7 8.9)
или так:
>sum . replicate 5 $ max 6.7 8.9
Функция >replicate 5
применяется к результату вычисления >max 6.7 8.9
, после чего элементы полученного списка суммируются. Обратите внимание, что функция >replicate
частично применена так, чтобы у неё остался только один параметр, так что теперь результат >max 6.7 8.9
передаётся на вход >replicate 5
; новым результатом оказывается список чисел, который потом передаётся функции >sum
.
Если вы хотите переписать выражение с кучей скобок, используя функциональную композицию, можно сначала записать самую внутреннюю функцию с её параметрами, затем поставить перед ней знак >$
, а после этого пристраивать вызовы всех других функций, записывая их без последнего параметра и разделяя точками. Например, выражение
>replicate 2 (product (map (*3) (zipWith max [1,2] [4,5])))
можно переписать так:
>replicate 2 . product . map (*3) $ zipWith max [1,2] [4,5]
Как из одного выражения получилось другое? Ну, во-первых, мы посмотрели на самую правую функцию и её параметры как раз перед группой закрывающихся скобок. Это функция >zipWith max [1,2] [4,5]
. Так её и запишем:
>zipWith max [1,2] [4,5]
Затем смотрим на функцию, которая применяется к >zipWith max [1,2] [4,5]
, это >map (*3)
. Поэтому мы ставим между ней и тем, что было раньше, знак >$
:
>map (*3) $ zipWith max [1,2] [4,5]
Теперь начинаются композиции. Проверяем, какая функция применяется ко всему этому, и присоединяем её к >map (*3)
:
>product . map (*3) $ zipWith max [1,2] [4,5]
Наконец, дописываем функцию >replicate 2
и получаем окончательное выражение:
>replicate 2 . product . map (*3) $ zipWith max [1,2] [4,5]
Если выражение заканчивалось на три закрывающие скобки, велики шансы, что у вас получится два оператора композиции.