Законы Монады, выраженные в терминах объединения вместо привязки?

Традиции монады традиционно описываются в терминах >>= и pure:

pure a >>= k = k a
m >>= pure = m
m >>= (\x -> k x >>= h) = (m >>= k) >>= h

Однако, монады также могут быть определены в терминах join вместо >>=. Я хотел бы придумать формулировку законов монады в терминах join.

Используя x >>= f = join (fmap f x), его легко переписать существующие законы монады, чтобы устранить >>=. Упрощая результаты с помощью прикладных законов, первые два закона довольно приятно выражены:

join . pure = id
join . fmap pure = id

Интуиция для этих законов также проста, так как ясно, что введение дополнительного "слоя" с pure должно быть no-op в сочетании с join. Однако третий закон не так хорош. Он выглядит следующим образом:

  join (fmap (\x -> join (fmap h (k x))) m)
= join (fmap h (join (fmap k m)))

Это не приятно уменьшает использование прикладных законов, и его гораздо труднее понять, не глядя на него какое-то время. У него, конечно же, нет такой же легкой интуиции.

Существует ли эквивалентная альтернативная формулировка законов монады в терминах join, которую легче понять? В качестве альтернативы, есть ли способ упростить вышеупомянутый закон или облегчить его поиск? Версия с >>= уже менее приятна, чем версия, выраженная композицией Kleisli, но версия с join почти нечитаема.

Ответы

Ответ 1

Украдены прямо из Википедии:

(Естественное преобразование η: 1 → T pure; естественное преобразование µ: T^2 → T является join)

µ. Tµ = µ. µT

В Хаскеле:

join . fmap join = join . join

По-английски: если вы начинаете с трех слоев монады как mmma :: Monad m => m (m (ma)), не имеет значения, будете ли вы сначала выравнивать его внутренний слой, а затем внешний, или сначала будете выравнивать его внешний слой и тогда внутренний. Это тот же закон, который вы указали в качестве третьего (ассоциативность).

µ. Tη = µ. ηT = 1

В Хаскеле:

join. fmap pure = join. pure = id

По-английски: если вы начинаете с одного слоя монады как ma :: Monad m => ma, не имеет значения, создаете ли вы новый слой внутри него, а затем выравниваете его, или если вы создаете новый слой вне него, а затем сгладить это, и оба - то же самое, что вообще ничего не делать. Этот закон является комбинацией ваших первых двух.

Кроме того, join является естественной трансформацией означает, что

join. fmap (fmap f) = fmap f. join

из-за параметричности.