Монада мощнее, чем Applicative?
я смотрел напрошедшее обсуждение но не мог понять, почему любой из ответов на самом деле правильный.
Прикладное
<*> :: f (a -> b) -> f a -> f b
монада
(>>=) :: m a -> (a -> m b) -> m b
Так что, если я правильно понимаю, утверждение заключается в том, что>>=
не может быть написано, только предполагая существование<*>
Ну, давайте предположим, что у меня есть<*>
.
И я хочу создать>>=
.
Так что яf a
.
я имеюf (a -> b)
.
Теперь, когда вы смотрите на это,f (a -> b)
можно записать как(a -> b)
(если что-то является функцией от x, y, z - тогда это также функция от x, y).
Так из существования<*>
мы получаем(a -> b) -> f a -> f b
который снова может быть записан как((a -> b) -> f a) -> f b
, который можно записать как(a -> f b)
.
Итак, мы имеемf a
, у нас есть(a -> f b)
и мы знаем, что<*>
результаты вf b
Итак, мы получаем:
f a -> (a -> f b) -> f b
которая является монадой.
На самом деле, на более интуитивном языке: при реализации<*>
Извлекаю(a -> b)
снаружиf(a -> b)
Извлекаюa
снаружиf a
, а затем я применяю(a -> b)
наa
и получитьb
с которыми я завернутьf
наконец-то получитьf b
.
Так что я делаю почти то же самое, чтобы создать>>=
, После применения(a -> b)
наa
и получатьb
, сделайте еще один шаг и заверните егоf
так я вернусьf b
следовательно, я знаю, что у меня есть функция(a -> f b)
.