Haskell list comprehension question

Started by
4 comments, last by programmer88 16 years, 6 months ago
I often want to do something by generating an infinite list where each element is always greater than or equal to the previous, and then generating a finite list from this. However, doing something like (yes, this particular case is a stupid example, but the principle is there):
naturals = [1..]
naturalslessthan1000 = [x | x <- naturals, x < 1000]
Is there some way of stopping the second list comprehension at the first element where the condition x < 1000 fails? This means that, for example, I can then do foldr (+) 0 naturalslessthan1000.
[TheUnbeliever]
Advertisement
A list comprehension will always evaluate every item in the list. Your specific example can easily be solved though:

naturalslessthan1000 = takeWhile (<1000) naturals

Oh, and using the sum function rather than foldr (+) 0 is much more readable.
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
Quote:Original post by Luctus
A list comprehension will always evaluate every item in the list. Your specific example can easily be solved though:

naturalslessthan1000 = takeWhile (<1000) naturals


takeWhile will solve the cases that I'm thinking of, thanks.

Quote:Oh, and using the sum function rather than foldr (+) 0 is much more readable.


Great, thanks. I'm still familiarising myself with the Prelude.
[TheUnbeliever]
Quote:Original post by Luctus
A list comprehension will always evaluate every item in the list
I realized I formulated myself poorly here though as list comprehensions are indeed evaluated lazily. To be more correct: A list comprehension will always evaluate at least as many elements as the function consuming the list comprehension needs.

So for example take 1000 [x | x <- naturals] will evaluate 1000 elements from naturals, while take 1000 [x | x <- naturals, even x] will evaluate 2000 elements.
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
I realised what you meant. :-)

My previous hackish workaround had relied on this -- I'd print (in the interpreter) the full extent of the list, wait until it hung, kill it, and then return to take just as many as had worked. I think you can understand why I thought that there had to be a better way!
[TheUnbeliever]
Why are you learning haskell? I had to learn it at University...*shudders*

This topic is closed to new replies.

Advertisement