Функция >map
берёт функцию и список и применяет функцию к каждому элементу списка, формируя новый список. Давайте изучим сигнатуру этой функции и посмотрим, как она определена.
>map :: (a –> b) –> [a] –> [b]
>map _ [] = []
>map f (x:xs) = f x : map f xs
Сигнатура функции говорит нам, что функция >map
принимает на вход функцию, которая вычисляет значение типа >b
по параметру типа >a
, список элементов типа >a
и возвращает список элементов типа >b
. Интересно, что глядя на сигнатуру функции вы уже можете сказать, что она делает. Функция >map
– одна из самых универсальных ФВП, и она может использоваться миллионом разных способов. Рассмотрим её в действии:
>ghci> map (+3) [1,5,3,1,6]
>[4,8,6,4,9]
>ghci> map (++ "!") ["БУХ", "БАХ", "ПАФ"]
>["БУХ!","БАХ!","ПАФ!"]
>ghci> map (replicate 3) [3..6]
>[[3,3,3],[4,4,4],[5,5,5],[6,6,6]]
>ghci> map (map (^2)) [[1,2],[3,4,5,6],[7,8]]
>[[1,4],[9,16,25,36],[49,64]]
>ghci> map fst [(1,2),(3,5),(6,3),(2,6),(2,5)]
>[1,3,6,2,2]
Возможно, вы заметили, что нечто аналогичное можно сделать с помощью генератора списков. Вызов >map (+3) [1,5,3,1,6]
– это то же самое, что и >[x+3 | x <– [1,5,3,1,6]]
. Тем не менее использование функции >map
обеспечивает более читаемый код в случаях, когда вы просто применяете некоторую функцию к списку. Особенно когда применяются отображения к отображениям (>map
– к результатам выполнения функции >map
): тогда всё выражение с кучей скобок может стать нечитаемым.
Функция >filter
принимает предикат и список, а затем возвращает список элементов, удовлетворяющих предикату. Предикат – это функция, которая говорит, является ли что-то истиной или ложью, – то есть функция, возвращающая булевское значение. Сигнатура функции и её реализация:
>filter :: (a –> Bool) –> [a] –> [a]
>filter _ [] = []
>filter p (x:xs)
> | p x = x : filter p xs
> | otherwise = filter p xs
Довольно просто. Если выражение