Sign in to follow this  

Haskell list comprehension question

This topic is 3717 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites

This topic is 3717 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this