yjtools-0.9.9: Control/Monad/Tools.hs
module Control.Monad.Tools (
ifM
, whenM
, unlessM
, doWhile_
, doWhile
, doUntil_
, doUntil
, for_
, for
, filterM
, repeatM
, repeatM_
, skipRet
) 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_, doUntil_ :: Monad m => m Bool -> m ()
doWhile_ act = do p <- act
when p $ doWhile_ act
doUntil_ act = do p <- act
unless p $ doUntil_ act
doWhile, doUntil :: 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
doUntil i act = do (r, p) <- act i
if p then return r
else doUntil r act
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
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM _ [] = return []
filterM p (x:xs) = do
b <- p x
rs <- filterM p xs
if b then return $ x:rs
else return rs
repeatM :: Monad m => m a -> m [ a ]
repeatM = sequence . repeat
repeatM_ :: Monad m => m a -> m ()
repeatM_ = sequence_ . repeat
skipRet :: Monad m => m b -> a -> m a
skipRet p x = p >> return x