Несколько дополнительных замечаний, чтобы сделать связь между Reid Barton's general answer и конкретным конкретным вопросом более явным.
В этом случае, действительно окупается отработать свой Monad
экземпляр в терминах join
:
join' :: m (n (m (n b))) -> m (n b)
join' = fmap join . join . fmap sequence
По реинтродукции compose
/getCompose
в соответствующих местах и с помощью m >>= f = join (fmap f m)
, вы можете убедиться, что это действительно эквивалентно вашему определению (обратите внимание, что ваш prebind
равен fmap f
в этом уравнении).
Это определение позволяет проверить законы с диаграммами . Вот один для join . return = id
т.е. (fmap join . join . fmap sequence) . (return . return) = id
:
MT id MT id MT id MT
----> ----> ---->
rT2 | | rT1 | | rT1 | | id
rM3 V V rM3 V V V V
----> ----> ---->
MTMT sM2 MMTT jM2 MTT jT0 MT
Общего прямоугольник монады закон:
M id M
---->
rM1 | | id
V V
---->
MM jM0 M
Игнорирования частей, которые обязательно совпадает в обоих направлениях через квадраты, мы видим, что две крайние правые квадраты равны одному и тому же закону. (Конечно, немного глупо называть эти «квадраты» и «прямоугольники», учитывая все стороны, которые у них есть, но он лучше подходит моим ограниченным навыкам искусства ASCII.) Первый квадрат, однако, составляет sequence . return = fmap return
, что нижняя правая диаграмма на странице Википедии Reid Barton упоминает ...
M id M
---->
rT1 | | rT0
V V
---->
TM sM1 MT
... и это не учитывая, что это справедливо, так как Рид Бартона ответ показывает.
Если мы применим ту же стратегию к закону join . fmap return = id
, появится верхняя правая диаграмма, sequence . fmap return = return
- что, однако, не является проблемой сама по себе, поскольку это просто (немедленное следствие) закон об идентичности Traversable
. Наконец, то же самое с законом join . fmap join = join . join
делает две другие диаграммы - sequence . fmap join = join . fmap sequence . sequence
и sequence . join = join . sequence . fmap sequence
- весна вперед.
Сноски:
- Легенда для стенографии:
r
является return
, s
является sequence
и j
является join
. Буквы и цифры в верхнем регистре после аббревиатур функции устраняют неоднозначность участвующей монады, а позиция, введенная им или измененным слоем , заканчивается на - в случае s
, это относится к тому, что первоначально внутренний слой, как в этом Если мы знаем, что внешний слой всегда равен T
. Слои пронумерованы снизу вверх, начиная с нуля. Композиция указана путем написания стенограммы для второй функции ниже первой.
[Здесь] (http://www.math.mcgill.ca/barr/papers/ttt.pdf) - отличная книга, которая охватывает эту тему с точки зрения теории категорий (в частности, p257 "Distributive законы ") и дает * относительно * (с точки зрения того, кто уже знает теорию категорий ...) простое доказательство необходимого условия для' M. N', чтобы быть монадой, если 'M' и' N' являются монадами. [Здесь] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors) - еще один вопрос, который представляет небольшую вариацию кода, который вы указали, - возможно, это была бы более полезная отправная точка , – user2407038
Спойлер: есть. – user2407038
Lol, спасибо! Я прочитал эту ветку не так давно, но пропустил [этот комментарий] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors#comment47075703_29454112), который содержит положительный ответ. –