列表理解与无限列表

时间:2014-11-12 01:58:26

标签: haskell

我试过了:

[x * y | x <- [1..], y <- [1..], even x, even y]

无法运行,ghci只是挂起。

但是

[x * y | x <- [1..], even x, y <- [1..], even y]

的工作原理。

有人可以解释原因吗?谢谢!

2 个答案:

答案 0 :(得分:4)

在第一个版本中,在守卫之前,(x, y)生成为[(1, 1), (1, 2), (1, 3), (1, 4), ...)],因此even x后卫对所有人都失败了,但它永远不会到达x 1}}会变成2,所以没有(x, y)对通过守卫。

在第二个版本中,x生成为[1, 2, 3, ...],第一个保护会过滤掉1,因此它只能生成y x已设置为2。因此,这意味着(x, y)现在生成为[(2, 1), (2, 2), (2, 3), (2, 4), ...]。然后第二个守卫将其过滤到[(2, 2), (2, 4), ...];这些数字然后成倍增加并产生。

请注意,虽然第二个版本在这个意义上是高效的,但由于上述原因,它永远不会考虑除{2}以外的任何x

更好的解决方案是枚举数字对,使y不会使xhaskell infinite list of incrementing pairs

挨饿

答案 1 :(得分:0)

谓词应该遵循各自的绑定,就像你的第二个例子一样。然后你可以把它想象成一个嵌套循环:

for each x:
  if x even:
    for each y:
       if y even:
         x * y

由于y是无限列表,因此x只会考虑2个。