52700.fb2
При этом важно понимать, что по смыслу это три одинаковые функции. Они обозначают операцию по-
следовательного применения функций. Разные значки отражают разные типы функций аргументов.
Обобщённая формулировка категории Клейсли
Отметим, что мы могли бы сформулировать класс Kleisli и в более общем виде с помощью класса
Category:
class Kleisli m where
idK
:: Category cat => cat a (m a)
(*> ) :: Category cat => cat a (m b) -> cat b (m c) -> cat a (m c)
(+> ) :: (Category cat, Kleisli m)
=> cat a (m b) -> cat b c -> cat a (m c)
f +> g = f *> (g >> idK)
Мы заменили функциональный тип на его обобщение. Для наглядности мы будем пользоваться специ-
альной формулировкой со стрелочным типом.
Для этого мы определим модуль Kleisli. hs
module Kleisli where
import Prelude hiding (id, (>> ))
class Category cat where
id
:: cat a a
(>> ) :: cat a b -> cat b c -> cat a c
class Kleisli m where
idK
:: a -> m a
(*> ) :: (a -> m b) -> (b -> m c) -> (a -> m c)
(+> ) :: Kleisli m => (a -> m b) -> (b -> c) -> (a -> m c)
f +> g = f *> (g >> idK)
-- Экземпляр для функций
instance Category (-> ) where
id
= \x -> x
f >> g
= \x -> g (f x)
Мы не будем импортировать функцию id, а определим её в классе Category. Также в Prelude уже опре-
делена функция (>> ) мы спрячем её с помощью специальной директивы hiding для того, чтобы она нам не
мешалась. Далее мы будем дополнять этот модуль экземплярами класса Kleisli и примерами.
6.2 Примеры специальных функций
Частично определённые функции
Частично определённые функции – это такие функции, которые определены не для всех значений аргу-
ментов. Примером такой функции может быть функция поиска предыдущего числа для натуральных чисел.
Поскольку числа натуральные, то для нуля такого числа нет. Для описания этого поведения мы можем вос-
пользоваться специальным типом Maybe. Посмотрим на его определение:
data Maybe a = Nothing | Just a
deriving (Show, Eq, Ord)
88 | Глава 6: Функторы и монады: теория
a
f
b
Nothing