Haskell 理解(>;>;=)。(>;>;=)

Haskell 理解(>;>;=)。(>;>;=),haskell,monads,function-composition,Haskell,Monads,Function Composition,我试图理解(>>=)。(>>=),GHCi告诉我: (>>=) :: Monad m => m a -> (a -> m b) -> m b (>>=).(>>=) :: Monad m => m a -> (m b -> (a -> m b) -> b1) -> (a -> m b) -> b1 你能提供一个逐步解释结果是如何得出的吗 这篇作文用过吗 更新: 我能算出fma

我试图理解
(>>=)。(>>=)
,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->ma)->a1->(a->mb)->mb
,但接下来的事情开始变得有点混乱。任何帮助都将不胜感激,请在这里学习。

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=>ma
((i->kj)->kj)
在同一个位置。这可能吗?如果有Monad实例,这是可能的

Monad k => (->) (i -> k j)
原来有一个,就是

instance Monad ((->) r)
对于任何
r
。 现在我们的外部单子
m
((->)(i->kj)
,因此我们将所有出现的
m
替换为
(i->kj)->

(.) (>>=) ::             (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~ki
a~kj
,我们将以

(.) (>>=) ::             (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
(>>=) . (>>=) :: Monad m => m a -> (m b2 -> (a -> m b2) -> b) -> (a -> m b2) -> b
最后,我们将
k
重命名为
m
i
重命名为
a
j
重命名为
b2
,最后得到

(.) (>>=) ::             (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
(>>=) . (>>=) :: Monad m => m a -> (m b2 -> (a -> m b2) -> b) -> (a -> m b2) -> b

你自己尝试过派生它吗?你在哪里被卡住了?关于堆栈溢出已经有很多问题,它们一步一步地演示了如何派生类型,例如返回值应该是
b1
,而不是
b
。这怎么会是它的副本呢?@dfeuer它不是。它只是类似于@dfeuer,这是因为
(>=)
将函数作为其第二个参数,如果我们使用翻转版本(如
fmap
travel
foldMap
将函数映射到函数)
(=mb)->ma->mb
我们得到以下
(=mb
非常类似于
fmap.fmap
traverse.traverse
。还要注意
((=