Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List comprehension with infinity list

Tags:

haskell

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!

like image 976
CSnerd Avatar asked Oct 26 '25 01:10

CSnerd


1 Answers

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

like image 68
Cactus Avatar answered Oct 28 '25 01:10

Cactus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!