Стрелки Клейсли

Стрелка Клейсли — это функция, чей результат завёрнут в монаду:

a -> m b

Монадический код — это цепочки функций вида aa mb\to m\,b: каждая что-то считает и попутно порождает контекст. Хочется складывать их так же легко, как чистые функции точкой (.)\mathtt{(.)}. Стрелки Клейсли и их композиция дают ровно это. Обычная функция aa b\to b — её частный случай (контекст тривиален).

Две стрелки Клейсли склеиваются в одну — это композиция Клейсли (её оператор зовут «рыбкой»):

(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)
(<=<) :: (b -> m c) -> (a -> m b) -> (a -> m c)   -- обратная «рыбка»

-- композиция Клейсли выражается через bind монады:
(f >=> g) x = f x >>= g

Обратный порядок пишут (<=<)(\mathbin{\mathtt{<=<}}) — он читается как обычная композиция (.)\mathtt{(.)}. Тождественная стрелка — pure\mathtt{pure} (она же return\mathtt{return}):

pure :: a -> m a

Возьмём пример из предыдущего раздела и перепишем его на стрелках:

-- в разделе про монады было:
processNumber x = pure x >>= halveEven >>= halveAndScale

-- на стрелках Клейсли — без аргумента и без pure:
processNumber = halveEven >=> halveAndScale

Скоро мы поговорим детальнее про категории, а тут пока скажем пару слов, а именно, возьмём типы за объекты, стрелки Клейсли за морфизмы, (>=>)(\mathbin{\mathtt{>=>}}) за композицию, а pure\mathtt{pure} за тождество — получится категория Клейсли. Её аксиомы — это в точности законы монады:

pure >=> f == f                       -- единица
f >=> pure == f
(f >=> g) >=> h == f >=> (g >=> h)    -- ассоциативность

То есть «монада» и «категория Клейсли» — два названия одного и того же. Законы, которые через >>=\mathbin{\mathtt{>>=}} выглядят громоздко, здесь становятся привычными.