>>= 和 concatMap 的区别
Difference between >>= and concatMap
我今天在玩 >>=
,试图理解 monad,并发现了一个有趣的模式。当使用列表 monad 时,>>=
的行为似乎像 concatMap。我四处搜索试图找到任何相似之处,特别是在 hackage 的定义中。
我试过的一些东西:
[1, 2, 3] >>= (iter 5 id) => [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
concatMap (iter 5 id) [1, 2, 3]=> [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
[1, 2, 3] >>= (iter 5 (+5)) => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
concatMap (iter 5 (+5) ) [1, 2, 3] => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
iter
只是非无限迭代,
iter i f a = toL $ Data.Sequence.iterateN i f a
where
toL = Data.Foldable.toList :: Data.Sequence.Seq a -> [a]
(在 repl.it 工作,所以进口被搞砸了)。
(>>=)
是否等同于列表的 concatMap
?
是concatMap
的泛化吗?
是的,(=<<)
是 concatMap
列表。对于任何 Monad,>>=
只是 fmap
和 join
(concat
的概括)的组合,因此这也具有直观意义。
是的,参数颠倒了。比较这些类型签名应该会发现相似性,尽管特殊的列表语法会干扰:
Prelude> :t flip concatMap
flip concatMap :: Foldable t => t a -> (a -> [b]) -> [b]
Prelude> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
我今天在玩 >>=
,试图理解 monad,并发现了一个有趣的模式。当使用列表 monad 时,>>=
的行为似乎像 concatMap。我四处搜索试图找到任何相似之处,特别是在 hackage 的定义中。
我试过的一些东西:
[1, 2, 3] >>= (iter 5 id) => [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
concatMap (iter 5 id) [1, 2, 3]=> [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
[1, 2, 3] >>= (iter 5 (+5)) => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
concatMap (iter 5 (+5) ) [1, 2, 3] => [1,6,11,16,21,2,7,12,17,22,3,8,13,18,23]
iter
只是非无限迭代,
iter i f a = toL $ Data.Sequence.iterateN i f a
where
toL = Data.Foldable.toList :: Data.Sequence.Seq a -> [a]
(在 repl.it 工作,所以进口被搞砸了)。
(>>=)
是否等同于列表的 concatMap
?
是concatMap
的泛化吗?
是的,(=<<)
是 concatMap
列表。对于任何 Monad,>>=
只是 fmap
和 join
(concat
的概括)的组合,因此这也具有直观意义。
是的,参数颠倒了。比较这些类型签名应该会发现相似性,尽管特殊的列表语法会干扰:
Prelude> :t flip concatMap
flip concatMap :: Foldable t => t a -> (a -> [b]) -> [b]
Prelude> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b