Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 无限列表的列表理解_Haskell - Fatal编程技术网

Haskell 无限列表的列表理解

Haskell 无限列表的列表理解,haskell,Haskell,我试过这个: [x * y | x <- [1..], y <- [1..], even x, even y] 工作 有人能解释一下原因吗?谢谢 在第一个版本中,在防护装置之前,(x,y)被生成为[(1,1)、(1,2)、(1,3)、(1,4),…),因此甚至x防护装置对所有防护装置都失败,但它永远不会达到x变成2的程度,因此没有(x,y)对通过防护装置 在第二个版本中,x被生成为[1,2,3,…],第一个保护过滤掉1,因此它只能在x已设置为2的情况下生成y。这意味着(x,y)现在

我试过这个:

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


有人能解释一下原因吗?谢谢

在第一个版本中,在防护装置之前,
(x,y)
被生成为
[(1,1)、(1,2)、(1,3)、(1,4),…)
,因此
甚至x
防护装置对所有防护装置都失败,但它永远不会达到
x
变成2的程度,因此没有
(x,y)
对通过防护装置

在第二个版本中,
x
被生成为
[1,2,3,…]
,第一个保护过滤掉
1
,因此它只能在
x
已设置为
2
的情况下生成
y
。这意味着
(x,y)
现在被生成为
[(2,1),(2,2),(2,3),(2,4),…]
。然后,第二个防护将其过滤为
[(2,2),(2,4),…]
;这些是随后乘以并得出的数字

注意,虽然第二个版本在这个意义上是有生产力的,但它不会考虑任何<代码> x>代码> 2以外,因为上面的原因。


更好的解决方案是以这样的方式枚举数对:
y
不会耗尽
x

谓词应该遵循各自的绑定,如第二个示例中所示。然后您可以将其视为嵌套循环:

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

由于
y
s是一个无限列表,因此
x

只考虑2个,GHCI不是“挂起”,它只是在做一些需要花费很多时间的事情,或者是没有尽头的事情。因此,您的代码可能有效,但时间复杂度太大。这并不意味着第二个示例将枚举
4*2
,这相当于枚举所有有理数。您必须通过在二维表示中的交叉对角线上迭代,将两个无穷大转换为一个无穷大……而且
[2,4..]
将为您提供所有可能的
for each x:
  if x even:
    for each y:
       if y even:
         x * y