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