module Control.Monad.Utils ( ifM , whenM , unlessM , doWhile_ , doWhile , for_ , for ) where import Control.Monad (when, unless) ifM :: Monad m => m Bool -> m a -> m a -> m a ifM p t e = do b <- p if b then t else e whenM, unlessM :: Monad m => m Bool -> m () -> m () whenM p t = p >>= flip when t unlessM p e = p >>= flip unless e doWhile_ :: Monad m => m Bool -> m () doWhile_ act = do p <- act when p $ doWhile_ act doWhile :: Monad m => a -> (a -> m (a, Bool)) -> m a doWhile i act = do (r, p) <- act i if p then doWhile r act else return r for_ :: Monad m => a -> (a -> Bool) -> (a -> a) -> (a -> m b) -> m () for_ i test next act | test i = act i >> for_ (next i) test next act | otherwise = return () for :: Monad m => a -> (a -> Bool) -> (a -> a) -> b -> (a -> b -> m b) -> m b for i test next j act | test i = act i j >>= flip (for (next i) test next) act | otherwise = return j