I have the following code that implements the Sieve of Eratosthenes:
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]))
I would like to change main to something like
main = print (sum [p | p <- primes, p < 100000]))
Not surprisingly, this hangs because it must compare p against every element of the infinite list primes. Since I know that primes is in increasing order, how do I truncate the infinite list as soon as I find an element that exceeds my upper limit?
p.s. In theory, primes' filters the input list to return a list of primes. I know there will be some issues if I start the list at something other than 2. I'm still working on how to address this issue on my own, so please no spoilers. Thanks ;-)
In cases like this where you know that once the predicate returns false for an element, it won't ever return true for a later element, you can replace filter
with takeWhile
, which stops taking elements as soon as the predicate returns false for the first time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With