我试图理解(>>=).(>>=)
,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
,但后事情开始变得有些混乱。任何帮助将不胜感激,只是想在这里学习。
答案 0 :(得分:10)
TL; DR :我们在中间使用((->) r
monad实例。
我们必须看(.) (>>=)
。那么让我们首先重复这些类型:
(>>=) :: 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
。
现在我们的外部monad 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
,最后我们} p>
(>>=) . (>>=) :: Monad m => m a -> (m b2 -> (a -> m b2) -> b) -> (a -> m b2) -> b