[英]Haskell Monadic Operations on Lists
我有以下內容
[3,2,1] >> [1]
= [1,1,1]
我完全不明白為什么會這樣? 看看>>我希望[3,2,1]成為結果,但我看到這在列表上有所不同。
有誰能解釋為什么?
對於任何monad,您可以將a >> b
翻譯為a >>= \\_ -> b
。 在列表monad中,綁定運算符(>>=)
是concatMap
,其參數被翻轉,因此您的示例等效於
concatMap (\_ -> [1]) [3, 2, 1]
您可以像這樣評價。
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
>>
可以像這樣定義:
ma >> mb = ma >>= const mb
(這不是它在[]
的Monad
實例中的實際定義,但這並不重要。)
在列表的情況下,對於[1,2,3]
每個元素,得到[1]
,整體結果等於concat [[1],[1],[1]]
,即[1,1,1]
。
這是GHC.Base中[]
的實例:
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
我們在這里使用折疊連接左側的每個元素的右側的一個副本,忽略該元素可能是什么。
回想一下列表的return
是\\x -> [x]
。 如果我在return
方面重寫你的例子,也許會更清楚
[1,2,3] >> return 1
讓我們添加一些做符號糖
do [1,2,3]
return 1
你現在能看到嗎? >>
不會從左邊的參數中提取值,只包括它們周圍的上下文 。 在這種情況下,上下文是一個3元素列表,或者您可能會說,3個不同的選擇都是非確定性地選擇的。 然后在每種情況下, return 1
。
如果你改為做了
do x <- [1,2,3]
return x
那么你不是在每種情況下都選擇1,而是x
,它代表每個“分支”的特定選擇。 試着猜猜結果是什么,然后檢查ghci以確定你是對的。 然后去除它,並使用等式推理來得到正確的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.