Понимание (>>=). (> > =)


Я пытаюсь понять (>>=).(>>=), что GHCi говорит мне:

(>>=)       :: Monad m => m a -> (a -> m b) -> m b
(>>=).(>>=) :: Monad m => m a -> (m b -> (a -> m b) -> b1) -> (a -> m b) -> b1

Можете ли вы дать пошаговое объяснение того, как получен результат?

А эта композиция когда-нибудь использовалась?

Обновление:

Я могу работать fmap.fmap, но не бросить (>>=).(>>=), я могу добраться до (.)(>>=) :: Monad m => (a1 -> m a) -> a1 -> (a -> m b) -> m b, но послесловие начинает немного запутываться. Любая помощь была бы оценена, просто попытайтесь узнать здесь.

1 4

1 ответ:

TL; DR : мы используем экземпляр ((->) r монады между ними.


Мы должны посмотреть на (.) (>>=). Итак, давайте сначала повторим типы:
(>>=) :: Monad m => m a -> ((a -> m b) -> m b)
(.)   ::            (y  -> z                 ) -> (x -> y) -> (x -> z)

Следовательно, мы имеем

(.) (>>=) :: Monad m => (x -> m a) -> (x -> ((a -> m b) -> m b))
-- or, with less parentheses
(.) (>>=) :: Monad m => (x -> m a) -> x -> (a -> m b) -> m b

Теперь мы подключаем другой (>>=):

(.) (>>=) :: Monad m => (x ->  m a               ) -> x -> (a -> m b) -> m b
(>>=)     :: Monad k => k i -> ((i -> k j) -> k j)
Но теперь у нас есть проблема. Мы имеем Monad m => m a и ((i -> k j) -> k j) в одной и той же позиции. Это вообще возможно? Ну, это возможно, если есть экземпляр монады для
Monad k => (->) (i -> k j)

Оказывается, есть один, а именно

instance Monad ((->) r)

Для любого r. Теперь наша внешняя монада m есть ((->) (i -> k j), поэтому мы заменяем все случаи m на (i -> k j) ->:

(.) (>>=) ::             (x -> (i -> k j) -> a) -> x -> (a -> (i -> k j) -> b) -> (i -> k j) -> b
(>>=)     :: Monad k => k i -> ((i -> k j) -> k j)

Теперь набор x ~ k i, a ~ k j и мы заканчиваем с

(.) (>>=) ::             (x -> (i -> k j) -> a) -> x -> (a -> (i -> k j) -> b) -> (i -> k j) -> b
(>>=)         :: Monad k => k i -> ((i -> k j) -> k j)
(>>=) . (>>=) :: Monad k => k i -> (k j -> (i -> k j) -> b) -> (i -> k j) -> b

Наконец, переименуем k в m, i к a и j к b2, и мы заканчиваем с

(>>=) . (>>=) :: Monad m => m a -> (m b2 -> (a -> m b2) -> b) -> (a -> m b2) -> b