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 ..]]
[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 ..]]