Haskell - 为什么这个列表理解 return 是一个无限列表?

Haskell - Why does this list comprehension return an infinite list?

[3 * x | x <- [1 ..], 3 * x < 20]

我真的不明白为什么会这样

[3,6,9,12,15,18

而且找不到尽头

的语义
[3 * x | x <- [1 ..], 3 * x < 20]

就是把[1..]的所有元素都试一遍,保留满足过滤条件的3*x<20.

人们可以看到,在第一个伪造条件的 x 之后,尝试所有更大的值是没有意义的,但是 Haskell 无论如何都会尝试那些,并卡在某种无限循环。

这是因为在一般情况下,条件可能会再次变为真,例如

[3 * x | x <- [1 ..], 3 * x < 20 || x == 1000000 ]

一般来说undecidable检测是否没有更多的解,所以Haskell和其他任何编程语言一样,不能选择在最后一个之后停止解决方案。

如果希望列表在第一个不满足过滤条件的值之后停止,使用takeWhile:

takeWhile (< 20) [3 * x | x <- [1 ..]]