ванными именами только для тех функций, для которых возможна коллизия имён можно поступить так:
70 | Глава 4: Декларативный и композиционный стиль
import qualified Prelude asP
import Prelude
Компилятор разберётся, какую функцию мы имеем в виду.
Для удобства тестирования можно определить такую функцию печати потоков:
instance Showa => Show( Streama) where
show xs =
showInfinity (show (take 5 xs))
whereshowInfinity x = P.init x
P.++”...”
Функция P.init выделяет все элементы списка кроме последнего. В данном случае она откусит от строки
закрывающуюся скобку. После этого мы добавляем троеточие, как символ бесконечности списка.
Функции преобразования потоков:
-- Преобразование потока
map ::(a ->b) -> Streama -> Streamb
-- Фильтрация потока
filter ::(a -> Bool) -> Streama -> Streama
-- zip-ы для потоков:
zip :: Streama -> Streamb -> Stream(a, b)
zipWith ::(a ->b ->c) -> Streama -> Streamb -> Streamc
Функция генерации потока:
iterate ::(a ->a) ->a -> Streama
Эта функция принимает два аргумента: функцию следующего элемента потока и значение первого эле-
мента потока и возвращает поток:
iterate f a =a :&f a :&f (f a) :&f (f (f a)) :& ...
Так с помощью этой функции можно создать поток всех чисел Пеано от нуля или постоянный поток:
nats
=iterate Succ Zero
constStream a
=iterate (\x ->x) a
Возможно вас удивляет тот факт, что в этом упражнении мы оперируем бесконечными значениями, но
пока мы не будем вдаваться в детали того как это работает, просто попробуйте определить этот модуль и
посмотрите в интерпретаторе, что получится.
Упражнения | 71
Глава 5
Функции высшего порядка
Функцией высшего порядка называют функцию, которая может принимать на вход функции или возвращать
функции в качестве результата. За счёт частичного применения в Haskell все функции, которые принимают
более одного аргумента, являются функциями высшего порядка.
В этой главе мы подробно обсудим способы составления функций, недаром Haskell – функциональный
язык. В Haskell функции являются очень гибким объектом, они позволяют выделять сложные способы ком-
бинирования значений. Часто за счёт развитых средств составления новых функций в Haskell пользователь
определяет лишь базовые функции, получая остальные “на лету” применением двух-трёх операций, это вы-
глядит примерно как (2 +3) *5, где вместо чисел стоят базовые функции, а операции +и *составляют новые
функции из простейших.
5.1 Обобщённые функции
В этом разделе мы познакомимся с несколькими функциями, которые принимают одни функции и состав-
ляют по ним другие. Эти функции используются в Haskell очень часто. Все они живут в модуле Data.Function.
Модуль Preludeэкспортирует их из этого модуля.
Функция тождества
Начнём с самой простой функции. Это функция id. Она ничего не делает с аргументом, просто возвращает
его:
id ::a ->a
id x =x
Зачем нам может понадобиться такая функция? Сама по себе она бесполезна. Она приобретает ценность
при совместном использовании с другими функциями, поэтому пока мы не будем приводить примеров.
Константная функция
Следующая функция const принимает значение и возвращает постоянную функцию. Эта функция будет
возвращать константу для любого переданного в неё значения:
const ::a ->b ->a
const a _ =a
Функция const является конструктором постоянных функций, так например мы получаем пятёрки на
любой аргумент:
Prelude> letonlyFive =const 5
Prelude> :t onlyFive
onlyFive ::b -> Integer
Prelude>onlyFive ”Hi”
5
Prelude>onlyFive (1,2,3)
5
Prelude>map onlyFive ”abracadabra”
[5,5,5,5,5,5,5,5,5,5,5]
72 | Глава 5: Функции высшего порядка
С её помощью мы можем легко построить и постоянную функцию двух аргументов:
const2 a =const (const a)
Вспомним определение для &&:
( &&) :: Bool -> Bool -> Bool
( &&) True
x
=x
( &&) False
_
= False
С помощью функций id и const мы можем сократить число аргументов и уравнений:
Читать дальше