I tried this:
[x * y | x <- [1..], y <- [1..], even x, even y]
This fails to run, the ghci
just hangs.
But
[x * y | x <- [1..], even x, y <- [1..], even y]
works.
Can someone explain why? Thanks!
I tried this:
[x * y | x <- [1..], y <- [1..], even x, even y]
This fails to run, the ghci
just hangs.
But
[x * y | x <- [1..], even x, y <- [1..], even y]
works.
Can someone explain why? Thanks!
In the first version, before the guards, (x, y)
are generated as [(1, 1), (1, 2), (1, 3), (1, 4), ...)]
, so the even x
guard fails for all of them, but it never gets to the point where x
would become 2, so no (x, y)
pair ever makes it through the guards.
In the second version, x
is generated as [1, 2, 3, ...]
, the first guard filters out 1
, so it only gets to generating y
with x
already set to 2
. So this means (x, y)
is now generated as [(2, 1), (2, 2), (2, 3), (2, 4), ...]
. The second guard then filters this down into [(2, 2), (2, 4), ...]
; these are the numbers which are then multiplied and yielded.
Note that while the second version is productive in this sense, it will never consider any x
other than 2, because of the reason outlined above.
A better solution would be to enumerate the pairs of numbers in such a way that the y
doesn't starve out the x
: haskell infinite list of incrementing pairs
The predicates are supposed to go after their respective bindings, like in your second example. Then you can think of it like a nested loop:
for each x:
if x even:
for each y:
if y even:
x * y
Since the y
s are an infinite list though, only 2 will be considered for x
.