我是这样想的:
[i | i <- [1..], i < 5]
会产生
[1, 2, 3, 4]
就像
take 4 [i | i <- [1..]]
一个有限长度的列表。
但不是,这似乎是无限的,因为任何将其视为有限列表的尝试都只会导致挂起(ghci)。
我不确定如何确切地理解这一点。是某种无限生成器,仅在第四项之后什么也不产生,却永不停止吗?
基本上,代码会不断生成新项目,因为它不知道它们永远无法满足条件?
答案 0 :(得分:5)
您从字面上告诉程序检查无限列表的每个元素,并且仅包括小于5的元素。正如您所说,编译器没有意识到列表的其余元素永远都不会满足条件。如果传递任意列表,即使在理论上也无法在运行时创建这样的证明。它只是按照您说的做,并且会不断检查每个元素。
如果程序由于懒惰求值而没有尝试对结果xs
中的1:2:3:4:xs
求值,则不一定是bug。服用head
应该很好。但是,如果您告诉它找到列表的长度或类似的内容,那将是一个无限循环。
一种(可能是?)想要做的事情的方法是takeWhile
,当条件不再成立时,它就会停止。