在Haskell中过滤无限列表

时间:2012-06-07 17:15:10

标签: list haskell

我有以下代码实现了Eratosthenes的Sieve:

primes :: [Int]
primes = primes' [2..]

primes' :: [Int] -> [Int]
primes' [] = []
primes' (p:ps) = p:(primes' [p' | p' <- ps, not (p' `isMultiple` p)])

a `isMultiple` b = (a `mod` b) == 0

main = print (sum (primes' [2..100000]))

我想将main更改为

main = print (sum [p | p <- primes, p < 100000]))

毫不奇怪,这会挂起,因为它必须将p与无限列表素数的每个元素进行比较。由于我知道素数的增加顺序,如何在找到超出上限的元素时如何截断无限列表呢?

P.S。理论上,素数'过滤输入列表以返回素数列表。我知道如果我以2以外的其他内容开始列表会有一些问题。我仍然在努力解决这个问题,所以请不要破坏它。谢谢; - )

1 个答案:

答案 0 :(得分:18)

在这种情况下你知道一旦谓词为一个元素返回false,它就不会为后面的元素返回true,你可以用filter替换takeWhile,这会停止服用一旦谓词第一次返回false,就会生成元素。