>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
.