Добрый день
Вопрос по программированию, но задаю в этом разделе, потому что в других он смотрится менее уместно.
Зафиксируем категорию типов (д.з.к.). Очевидно, что композиция любых двух функторов — это функтор. А что из себя представляет композиция двух монад?
(Мои рассуждения)
Пусть перед нами две монады
и
. Построим квадрат
он коммутирует по натуральности
и поэтому некий аналог единицы (относительно ещё непостроенной операции)
может быть построен.
А вот с умножением большие проблемы. Поскольку речь идёт о программировании, то основные монады —
State,
Maybe и
List. Рассмотрим композицию
MaybeState, умножение которой должно иметь тип
join :: Maybe (State (Maybe (State a))) -> Maybe (State a), причём по интуиции всё выражение
join (Just impureValue) должно возвращать
Nothing, если
impureValue возвращает
Nothing; но это невозможно, поскольку impureValue может менять состояние, а значит возвращаемый тип должен быть по меншей мере
State (Maybe a). И действительно, можно описать функцию
Maybe (State (Maybe (State a))) -> State (Maybe a) по принципу «внутри монады
State разворачиваем капусту из
Maybe, пока не дойдём до
Nothing и тогда его же и возвращаем или до значения, которое и возвращаем».
С другой стороны, рассмотрим подробнее
Maybe a = 1 + a, представленную (не знаю, как правильно это соответствие называется) функцией
maybe :: b -> (a -> b) -> Maybe a -> b, т.е.
Maybe a ~ forall b. b -> (a -> b) -> b или, по-другому,
maybe e f = const e + fПусть
m — некая монада. Объявим такую функцию:
Код:
join a = do
v <- a
case v of
Nothing -> return Nothing
Just b -> b
-- или
join = bind (maybe (return Nothing) id)
где
return —
, а
bind — это
. Введём обозначение
N = const Nothing и обратим вниманием, что
, как и
, является инъекцией. Перепишем функцию в виде
Докажем для примера
, т.е.
диаграммой
Верхний левый квадрат естественный для
, правый и нижний треугольники коммутируют по свойству нейтральности единицы отн. умножения для Maybe и m, соответственно.
Полагаю, остальные аксиомы доказываются таким же образом.
(Мои рассуждения 2)
Мне кажется, что для того, чтобы из монад
и
составить композитную монаду
, нужно, чтобы было натуральное преобразование
. Тогда можно ввести
. Однако, нужно бы что-то потребовать, чтобы удовлетворить аксиомам.
Если я правильно рассчитал по подобной прошлой диаграмме схеме, для аксиомы
нужно потребовать
Интуитивно, хочется разделить все монады на сильные (IO, State, Writer, Reader) и слабые (Maybe, Either, List), причём первые всегда должны быть где-то снаружи относительно вторых, так сказать, по наличию вышеуказанной функции
(например,
sequence :: [m a] -> m [a] указывает на слабость списков, а
maybe (return Nothing) id :: Maybe (m a) -> m (Maybe a) указывает на слабость
Maybe)
А что в литературе говориться по этому вопросу?