列表理解中的哈斯克尔懒惰

时间:2014-02-22 17:18:27

标签: haskell range list-comprehension

我想得到所有偶数的总和< = 1000。

以下代码:

sum [x | x <- [1..1000], even x](我知道可以用[2,4..1000]完成,这是为了练习)

报告总和为250500

然而:

sum [x | x <- [1..], even x && x <= 1000]

从未完成,必须被打断!

我认为我可以安全地编写[1..],这是一个无限列表,因为Haskell不会尝试评估它。

此外,我认为它只是简单地从x开始,检查它们并添加它们。

那么为什么上述结果不能产生结果?

1 个答案:

答案 0 :(得分:8)

sum [x | x <- [1..], even x && x <= 1000]

转换为类似

的内容
sum (filter (\x -> even x && x <= 1000) [1..])

范围表达式(或者,desugared,enumFrom)继续生成值,filter继续丢弃它们(它不知道永远不会有另一个元素满足谓词),但是sum永远不会到达列表的末尾,因此无法返回结果。一旦看到第一个值大于1000,您就想停止评估列表:

sum (takeWhile (<= 1000) $ filter even [1..])