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