52700.fb2
аргументы местами.
(>> ) :: (a -> b) -> (b -> c) -> (a -> c)
f >> g = \x -> g (f x)
Мы будем изображать функции кружками, а значения – стрелками (рис. 6.1). Значения словно текут от
узла к узлу по стрелкам. Поскольку тип стрелки выходящей из f совпадает с типом стрелки входящей в g мы
можем соединить их и получить составную функцию (f>> g).
a
f
b
b
g
c
b
a
g
f
c
a
f>>g
c
Рис. 6.1: Композиция функций
86 | Глава 6: Функторы и монады: теория
Класс Category
С помощью операции композиции можно обобщить понятие функции. Для этого существует класс
Category:
class Category cat where
id
:: cat a a
(>> ) :: cat a b -> cat b c -> cat a c
Функция cat это тип с двумя параметрами, в котором выделено специальное значение id, которое остав-
ляет аргумент без изменений. Также мы можем составлять из простых функций сложные с помощью компо-
зиции, если функции совпадают по типу. Здесь мы для наглядности также заменили метод (. ) на (>> ), но
суть остаётся прежней. Для любого экземпляра класса должны выполняться свойства:
f
>> id
== f
id >> f
== f
f >> (g >> h) == (f >> g) >> h
Первые два свойства говорят о том, что id является нейтральным элементом для (>> ) слева и справа.
Третье свойство говорит о том, что нам не важно в каком порядке проводить композицию. Можно проверить,
что эти правила выполнены для функций.
Специальные функции
Все специальные функции, которые мы рассмотрим в этой главе будут иметь один и тот же тип:
a -> m b
Смотрите вместо произвольного типа b функция возвращает m b. Единственное, что будет меняться от
раздела к разделу это тип m. Добавив этот тип к результату, мы сузили область значений функции. Простым
примером таких функций могут быть функции, которые возвращают списки:
a -> [b]