Изучай Haskell во имя добра! (Липовача) - страница 54

>numLongChains :: Int

>numLongChains = length (filter isLong (map chain [1..100]))

>  where isLong xs = length xs > 15

Мы применяем функцию >chain к списку >[1..100], чтобы получить список цепочек; цепочки также являются списками. Затем фильтруем их с помощью предиката, который проверяет длину цепочки. После фильтрации смотрим, как много цепочек осталось в результирующем списке.

ПРИМЕЧАНИЕ. Эта функция имеет тип >numLongChains :: Int, потому что >length возвращает значение типа >Int вместо экземпляра класса >Num – так уж сложилось исторически. Если мы хотим вернуть более общий тип, имеющий экземпляр класса >Num, нам надо применить функцию >fromIntegral к результату, возвращённому функцией >length.

Функция map для функций нескольких переменных

Используя функцию >map, можно проделывать, например, такие штуки: >map (*) [0..] – если не для какой-либо практической цели, то хотя бы для того, чтобы продемонстрировать, как работает каррирование, и показать, что функции (частично применённые) – это настоящие значения, которые можно передавать в другие функции или помещать в списки (но нельзя представлять в виде строк). До сих пор мы применяли к спискам только функции с одним параметром, вроде >map (*2) [0..], чтобы получить список типа >(Num a) => [a], но с тем же успехом можем использовать >(*) [0..] безо всяких проблем. При этом числа в списке будут применены к функции >*, тип которой >(Num a) => a –> a –> a. Применение только одного параметра к функции двух параметров возвращает функцию одного параметра. Применив оператор >* к списку >[0..], мы получаем список функций, которые принимают только один параметр, а именно >(Num a) => [a –> a]. Список, возвращаемый выражением >map (*) [0..], также можно получить, записав >[(0*),(1*),(2*),(3*),(4*),(5*)

>ghci> let listOfFuns = map (*) [0..]

>ghci> (listOfFuns !! 4) 5

>20

Элемент с номером четыре из списка содержит функцию, которая выполняет умножение на четыре – >(4*). Затем мы применяем значение >5 к этой функции. Это то же самое, что записать >(4*) 5 или просто >4 * 5.

Лямбда-выражения


Лямбда-выражения – это анонимные функции, которые используются, если некоторая функция нужна нам только однажды. Как правило, мы создаём анонимные функции с единственной целью: передать их функции высшего порядка в качестве параметра. Чтобы записать лямбда-выражение, пишем символ >\ (напоминающий, если хорошенько напрячь воображение, греческую букву лямбда – λ), затем записываем параметры, разделяя их пробелами. Далее пишем знак >–> и тело функции. Обычно мы заключаем лямбду в круглые скобки, иначе она продолжится до конца строки вправо.