bracketOnError, while, forever

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Mon Feb 7 08:37:53 EST 2005

```Peter Simons <simons at cryp.to> writes:

> On a similar note, I find myself using two rather simple
> combinators frequently but have no place where to put them:
>
>   while :: (Monad m) => m Bool -> m a -> m ()
>   while cond f = cond >>= flip when (f >> while cond f)
>
>   forever :: (Monad m) => m a -> m ()
>   forever f = while (return True) f
>

I agree that these sorts of combinators are frequently useful.  However,
there is a reasonable variety in the possible signatures one might
assign to the control-flow notion of "while".  For instance, how about

while :: Monad m => Bool -> m Bool -> m ()
while True f  = f >>= \b-> while b f
while False f = return ()

There are other control-flow analogies like

until :: Monad m => m Bool -> m ()
until f = f >>= \b-> if b then return () else until f

for :: Monad m => Int -> m a -> m ()
for   0   f = return ()
for (n+1) f = f >> for n f

which probably also have a few possible monadic variations.

Regards,
Malcolm
```