我无法理解接下来两行代码的工作方式。
ghci> take 6 [[(i,j) | i<-[2,4]] | j<-[1,3,5]]
[[(2,1),(4,1)],[(2,3),(4,3)],[(2,5),(4,5)]]
ghci> take 6 [[(i,j)] | i<-[2,4], j<-[1,3,5]]
[[(2,1)],[(2,3)],[(2,5)],[(4,1)],[(4,3)],[(4,5)]]
我明白 take 的作用,但我不明白这两行之间的区别以及迭代的顺序以及括号对代码的作用。我是 Haskell 的新手,如果我的问题很简单,我很抱歉。
区别不在于
take
,区别在于列表理解。第一个有 two 列表理解,以及 j <- [1,3,5]
outer 列表理解:
-- vvvvvvvvvvvvvvvvvv inner list comprehension
take 6 [[(i,j) | i<-[2,4]] | j<-[1,3,5]]
而后者有一个列表理解,因为
j <- [1,3,5]
是列表理解中的第二个“生成器”,即“内部”生成器。
这意味着在第一个变量中,
i
是变化最快的变量,而j
仅在i
完全耗尽后才发生变化,而对于第二个变量,则相反。
如果我们将其转换为 Python 中的某种生成器语法,它看起来像:
-- first example
for j in [1,3,5]:
for i in [2,4]:
yield [(i, j)]
-- second example
for i in [2,4]:
for j in [1,3,5]:
yield [(i, j)]
所以这意味着相同元素的生成方式顺序发生了变化。