Читаем Изучай Haskell во имя добра! полностью

sum $ filter (> 10) $ map (*2) [2..10]

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

ghci> map ($ 3) [(4+), (10*), ( 2), sqrt]

[7.0,30.0,9.0,1.7320508075688772]

Функция ($ 3) применяется к каждому элементу списка. Если задуматься о том, что она делает, то окажется, что она берёт функцию и применяет её к числу 3. Поэтому в данном примере каждая функция из списка применится к тройке, что, впрочем, и так очевидно.

<p>Композиция функций</p>

В математике композиция функций определяется следующим образом:

(f ° g)(x) = f (g (x))

Это значит, что композиция двух функций создаёт новую функцию, которая, когда её вызывают, скажем, с параметром x, эквивалентна вызову g с параметром x, а затем вызову f с результатом первого вызова в качестве своего параметра.

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

(.) :: (b –> c) –> (a –> b) –> a –> c

f . g = \x –> f (g x)

По декларации типа функция f должна принимать параметр того же типа, что и результат функции g. Таким образом, результирующая функция принимает параметр того же типа, что и функция g, и возвращает значение того же типа, что и функция f. Выражение negate . (* 3) возвращает функцию, которая принимает число, умножает его на три и меняет его знак на противоположный.

Одно из применений композиции функций – это создание функций «на лету» для передачи их другим функциям в качестве параметров. Конечно, мы можем использовать для этого анонимные функции, но зачастую композиция функций понятнее и лаконичнее. Допустим, что у нас есть список чисел и мы хотим сделать их отрицательными. Один из способов сделать это – получить абсолютное значение числа (модуль), а затем перевести его в отрицательное, вот так:

ghci> map (\x –> negate (abs x)) [5,–3,–6,7,–3,2,–19,24]

[–5,–3,–6,–7,–3,–2,–19,–24]

Обратите внимание на анонимную функцию и на то, как она похожа на результирующую композицию функций. А вот что выйдет, если мы воспользуемся композицией:

ghci> map (negate . abs) [5,–3,–6,7,–3,2,–19,24]

[–5,–3,–6,–7,–3,–2,–19,–24]

Невероятно! Композиция функций правоассоциативна, поэтому у нас есть возможность включать в неё много функций за один раз. Выражение f (g (z x)) эквивалентно (f . g . z) x. Учитывая это, мы можем превратить

ghci> map (\xs –> negate (sum (tail xs))) [[1..5],[3..6],[1..7]]

[–14,–15,–27]

в

ghci> map (negate . sum . tail) [[1..5],[3..6],[1..7]]

[–14,–15,–27]

Функция negate . sum . tail принимает список, применяет к нему функцию tail, суммирует результат и умножает полученное число на -1. Получаем точный эквивалент анонимной функции из предыдущего примера.

<p>Композиция функций с несколькими параметрами</p>

Ну а как насчёт функций, которые принимают несколько параметров? Если мы хотим использовать их в композиции, обычно мы частично применяем их до тех пор, пока не получим функцию, принимающую только один параметр. Запись

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]

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных