Haskell Monadic列表操作

Tob*_*bi3 2 monads haskell list

我有以下内容

[3,2,1] >> [1]
= [1,1,1]
Run Code Online (Sandbox Code Playgroud)

我完全不明白为什么会这样?看看>>我希望[3,2,1]成为结果,但我看到这在列表上有所不同.

有谁能解释为什么?

ham*_*mar 14

对于任何monad,你可以翻译a >> ba >>= \_ -> b.在列表单子,绑定运营商(>>=)concatMap用它的参数翻转,所以你的例子是相当于

concatMap (\_ -> [1]) [3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

您可以像这样评价.

concatMap (\_ -> [1]) [3, 2, 1]
= concat (map (\_ -> [1]) [3, 2, 1])   -- definition of concatMap
= concat [[1], [1], [1]]               -- apply map
= [1, 1, 1]                            -- apply concat
Run Code Online (Sandbox Code Playgroud)


ben*_*n w 7

>> 可以像这样定义:

ma >> mb = ma >>= const mb
Run Code Online (Sandbox Code Playgroud)

(这不是它在Monad实例中的实际定义[],但这并不重要.)

在列表的情况下,对于每个元素[1,2,3],你得到[1],整体结果相当于concat [[1],[1],[1]],即[1,1,1].

这是[]GHC.Base中的实例:

m >>= k             = foldr ((++) . k) [] m
m >> k              = foldr ((++) . (\ _ -> k)) [] m
Run Code Online (Sandbox Code Playgroud)

我们在这里使用折叠连接左侧的每个元素的右侧的一个副本,忽略该元素可能是什么.