How to get out of iterate loop when a condition is met?

Viewed 2008

I want to iterate over a function g with iterate. When I run my code the loop runs infinitely. Is there any possibility to get out of the loop when a condition is met?

Something like if g x > 100 then stop.

My code:

f x = iterate g x

g x = 2 * x
2 Answers

Just flip the condition, and takeWhile it holds:

f x = takeWhile (<= 100) $ iterate g x

Which could also be made point free:

f = takeWhile (<= 100) . iterate g

This will take from the infinite list that iterate returns while the accumulator is less than or equal to 100.

Yes, you either use takeWhile (not . p) for that, equivalent to

foldr (\x r -> if (not (p x)) then (x:r) else []) []

or sometimes the following is useful,

takeUntil p = foldr (\x r -> if (not (p x)) then (x:r) else [x]) []

if you want to include the last element into the sequence, as well.

In your case, you'd write takeWhile (not . (> 100)) . iterate (*2), or takeUntil (> 100) . iterate (*2).

(not . (> 100)) is of course the same as (<= 100).

Related