Reputation: 32334
I wanted to take a sum of all even numbers <= 1000.
The following code:
sum [x | x <- [1..1000], even x]
(I know it can be done with [2,4..1000], this is for practice)
reports that the sum is 250500
.
However:
sum [x | x <- [1..], even x && x <= 1000]
never finished and has to be interrupted!
I thought that I could safely write [1..]
, which is an infinite list, because Haskell would not try to evaluate it.
Furthermore, I thought that it would simply start going x by x, checking them and adding them.
So why does the above fail to produce a result?
Upvotes: 3
Views: 886
Reputation: 949
sum [x | x <- [1..], even x && x <= 1000]
translates to something like
sum (filter (\x -> even x && x <= 1000) [1..])
The range expression (or, desugared, enumFrom
) continues to generate values and filter
keeps discarding them (it doesn't know there'll never be another element that satisfies the predicate), but sum
never gets to the end of the list, so it can't return a result. You want to stop evaluating the list as soon as you see the first value greater than 1000:
sum (takeWhile (<= 1000) $ filter even [1..])
Upvotes: 11