Понимание (>>=). (> > =)
Я пытаюсь понять (>>=).(>>=)
, что 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 ответ:
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