[英]Haskell: Desugar List comprehension
我如何脫糖
λ: [[b|(a,b)<-[(1,"A"),(2,"B")], mod x 2 == 0]|x <- [1..10]]
[[],["A","B"],[],["A","B"],[],["A","B"],[],["A","B"],[],["A","B"]]
我努力了
do
x <- [1..10]
do
(a,b) <- [(1,"A"),(2,"B")]
guard $ mod x 2 == 0
return b
但這似乎會自動join
結果。
["A","B","A","B","A","B","A","B","A","B"]
請記住,嵌套do
構造了“崩潰”:
do
A
do B
C
是相同的
do
A
B
C
(或更准確地說,多行do
構造將desugar轉換為嵌套的do
構造。)因此,您希望構建子列表並將其添加到外部列表中,而不是使用嵌套的do
構造來構建單個列表來填充它。
使用混合中間方法,可以通過分別return
每個內部列表來構建外部列表。
do
x <- [1..10]
return [[b|(a,b)<-[(1,"A"),(2,"B")], mod x 2 == 0]
然后,您對這種理解力去糖化:
do
x <- [1..10]
return (do
(a, b) <- ...
guard $ mod x 2 == 0
return b)
由於您返回了列表理解,因此需要額外的return
:
do
x <- [1..10]
return $ do
(a,b) <- [(1,"A"),(2,"B")]
guard $ mod x 2 == 0
return b
否則,您將構造如下:
[b|x <- [1..10], (a,b)<-[(1,"A"),(2,"B")], mod x 2 == 0]
由於您在外部do
使用了do
作為尾元素,因此do
是多余的。
我對您的原始列表理解做了些微修改。
[ (x,[(b) | (a,b) <- [(1,"A"),(2,"B")], mod x 2 == 0]) | x <- [1..10] ]
導致
[(1,[]),(2,["A","B"]),(3,[]),(4,["A","B"]),(5,[]),(6,["A","B"]),(7,[]),(8,["A","B"]),(9,[]),(10,["A","B"])]
因此,使用這些參數,它會產生(a,b)或[]的b。
這翻譯成以下地圖。
map (\x -> if mod x 2 == 0 then [x] else [] ) [1..10]
哪個產生
[[],[2],[],[4],[],[6],[],[8],[],[10]]
您的列表理解的以下部分
[b|(a,b)<-[(1,"A"),(2,"B")]]
簡單生產
["A","B"]
下圖產生了相同的結果。
map snd [(1,"A"),(2,"B")]
將第一個地圖中的[x]替換為先前的地圖
map (\x -> if mod x 2 == 0 then map snd [(1,"A"),(2,"B")] else [] ) [1..10]
完全符合您的列表理解能力。 更改參數將得到相同的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.