bracketOnError, while, forever

Marcin 'Qrczak' Kowalczyk qrczak at
Mon Feb 7 08:37:17 EST 2005

Peter Simons <simons at> writes:

>   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

forever performs unnecessary computation which can't be optimized out
by the compiler before specializing the monad (because the compiler
can't use monad laws).

Why not
   forever f = f >> forever f
   forever f = loop where loop = f >> loop
I don't know which is better - I guess the second gives better space
behavior with some monads if it's not inlined (avoids recomputation of
identical copies), but maybe the first actually allows GHC to optimize
the case of IO better by not materializing a closure.

I don't like the point-free style of the first either.
   while cond f = do
      c <- cond
      when c (f >> while cond f)

   __("<         Marcin Kowalczyk
   \__/       qrczak at

More information about the Libraries mailing list