2017-04-12 74 views
2

今天我在玩>>=,试图理解monad,并发现了一个有趣的模式。在处理列表monad时,>>=似乎表现得像concatMap。我四处搜寻,试图找出任何相似之处,特别注意hackage的定义。>> =和concatMap之间的区别

有些事情我想:

[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的推广吗?

+0

见https://en.wikibooks.org/wiki/Haskell/Understanding_monads/List的执行情况进行深入的解释Monad的列表类型。也是https://wiki.haskell.org/All_About_Monads#List_is_also_a_monad。 – bheklilr

回答

5

是,是concatMap的列表。 >>=对于任何Monad来说只是fmapjoinconcat的推广)的组合,所以这也是直观的。

+0

感谢关于加入的一点,我从来没有真正意识到这一点! –

9

是的,参数翻转。比较这些类型签名要带出的相似性,虽然特殊的列表语法干扰:

Prelude> :t flip concatMap 
flip concatMap :: Foldable t => t a -> (a -> [b]) -> [b] 
Prelude> :t (>>=) 
(>>=)   :: Monad m => m a -> (a -> m b) -> m b 
+2

以前缀形式('Foldable t => ta - >(a - > [] b) - > [] b')编写列表类型构造函数是合法的,只是没有人这样做,因为它会导致更多的括号(' []([] a)'vs.'[[a]]')。 –