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