在Haskell的列表推导式中,如何组织元组的顺序?

4

大家好,

我正在尝试组织Haskell列表推导中元组的顺序。

例如,我有以下列表推导:

[ (a,b,c,d) | a <- [0, 50, 100, 150, 200]
            , b <- ['a', 'b', 'c']
            , c <- [True, False]
            , d <- ['A', 'B']
            ]

并获得:

[ (0, 'a', True, 'A'), (0, 'a', True, 'B'), (0, 'a', False, 'A')
, (0, 'a', False, 'B'), (0, 'b', True, 'A'), (0, 'b', True, 'B')
, (0, 'b', False, 'A'), (0, 'b', False, 'B'), (0, 'c', True, 'A')
,(0, 'c', True, 'B'), (0, 'c', False, 'A')..

现在我希望序列如下所示:
[ (0, 'a', True, 'A'), (0, 'a', True, 'B'), (0, 'b', True, 'A')
, (0, 'b', True, 'B'), (0, 'c' ,True, 'A'), (0, 'c', True, 'B')
, (0, 'a', False, 'A'), (0, 'a', False, 'B')..

那就是:首先在大写字母'A'和'B'之间进行权衡,然后在小写字母'a'、'b'、'c'之间进行权衡,倒数第二步是在布尔值'True'、'False'之间进行权衡,最后是数字。不幸的是,我完全不知道如何实现这些,我想知道如何使用元组[(a,b,c)]来操作列表的顺序。
1个回答

6

x <- list语句在列表推导式中的顺序很重要。如果你写成:

[expr | x <- list1, y <- list2]

这相当于具有内部循环的嵌套for循环。因此,使用循环的Python等价代码为:

y
for x in list1:
    for y in list2:
        expr

因此,在外部循环选择下一个值之前,内部循环完全耗尽。
因此,我们需要重新排列语句,使我们首先选择 d,然后是bc和最后是a。这意味着我们将以下语句改为:
[(a,b,c,d)| a <- [0,50..200], b <- "abc", c <- [True,False], d <-"AB"]

(我在符号方面使列表更短)

转换为:

-- [(a,b,c,d)| a <- [0,50..200], b <- "abc", c <- [True,False], d <-"AB"]
--             |                  \_________/_____              |
--             |                   ________/      \             |
--             |                  /                \            |
   [(a,b,c,d)| a <- [0,50..200], c <- [True,False], b <- "abc", d <- "AB"]

(该注释仅用于显示差异)

生成如下:

Prelude> [(a,b,c,d)| a <- [0,50..200], c <- [True,False], b <- "abc", d <- "AB"]
[(0,'a',True,'A'),
 (0,'a',True,'B'),
 (0,'b',True,'A'),
 (0,'b',True,'B'),
 (0,'c',True,'A'),
 (0,'c',True,'B'),
 (0,'a',False,'A'),
 (0,'a',False,'B'),
 (0,'b',False,'A'),
 (0,'b',False,'B'),
 (0,'c',False,'A'),
 (0,'c',False,'B'),
 (50,'a',True,'A'),
 (50,'a',True,'B'),
 (50,'b',True,'A'),
 (50,'b',True,'B'),
 (50,'c',True,'A'),
 (50,'c',True,'B'),
 (50,'a',False,'A'),
 (50,'a',False,'B'),
 (50,'b',False,'A'),
 (50,'b',False,'B'),
 (50,'c',False,'A'),
 (50,'c',False,'B'),
 (100,'a',True,'A'),
 (100,'a',True,'B'),
 (100,'b',True,'A'),
 (100,'b',True,'B'),
 (100,'c',True,'A'),
 (100,'c',True,'B'),
 (100,'a',False,'A'),
 (100,'a',False,'B'),
 (100,'b',False,'A'),
 (100,'b',False,'B'),
 (100,'c',False,'A'),
 (100,'c',False,'B'),
 (150,'a',True,'A'),
 (150,'a',True,'B'),
 (150,'b',True,'A'),
 (150,'b',True,'B'),
 (150,'c',True,'A'),
 (150,'c',True,'B'),
 (150,'a',False,'A'),
 (150,'a',False,'B'),
 (150,'b',False,'A'),
 (150,'b',False,'B'),
 (150,'c',False,'A'),
 (150,'c',False,'B'),
 (200,'a',True,'A'),
 (200,'a',True,'B'),
 (200,'b',True,'A'),
 (200,'b',True,'B'),
 (200,'c',True,'A'),
 (200,'c',True,'B'),
 (200,'a',False,'A'),
 (200,'a',False,'B'),
 (200,'b',False,'A'),
 (200,'b',False,'B'),
 (200,'c',False,'A'),
 (200,'c',False,'B')]

(new lines added to make it easier to verify)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接