列表推导中的警卫不会终止无限列表?

Cli*_*amp 1 haskell

我想这个:

[i | i <- [1..], i < 5]
Run Code Online (Sandbox Code Playgroud)

会产生

[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

就像

take 4 [i | i <- [1..]]
Run Code Online (Sandbox Code Playgroud)

有限长度列表.

但它没有,它似乎是无限的,因为任何将它视为有限列表的尝试只会导致挂起(ghci).

我不确定如何理解这一点.它是某种无限的发电机,它只是在第四项之后什么都不产生但从未停止过?

基本上代码不断生成新项目,因为它不知道它们永远不能满足标准?

Dav*_*lor 5

你实际上告诉程序检查无限列表的每个元素,并且只包括小于5的元素.正如你所说,编译器没有意识到列表的剩余元素不会满足条件.即使在理论上,如果传递任意列表,它也不可能在运行时创建这样的证明.它只是做你说的,并不断检查每个元素.

如果程序由于延迟评估而未尝试评估xs结果1:2:3:4:xs,则不一定是错误.服用head应该只是罚款.但是,如果你告诉它找到列表的长度或类似的东西,它就是一个无限循环.

你(可能?)想要做的事情的一种方法是takeWhile,当条件不再成立时停止.