我如何去除糖尿病
λ: [[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"]
答案 0 :(得分:4)
请记住,嵌套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)
答案 1 :(得分:2)
由于您返回列表理解,因此需要额外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
是多余的。
答案 2 :(得分:0)
我对你原来的列表理解做了一些小修改。
[ (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"])]
因此,使用这些参数,它产生b(a,b)或a []。
这转化为以下地图。
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]
完全符合你的列表理解。更改参数会产生相同的结果。