{-# LANGUAGE NoMonomorphismRestriction #-}
module Control.Monad.IfElse where
import Control.Monad
whenM :: Monad m => m Bool -> m () -> m ()
whenM test action = test >>= \t -> if t then action else return ()
cond :: Monad m => [(Bool, m ())] -> m ()
cond [] = return ()
cond ((True,action) : _) = action
cond ((False,_) : rest) = cond rest
condM :: Monad m => [(m Bool, m ())] -> m ()
condM [] = return ()
condM ((test,action) : rest) = test >>= \t -> if t then action else condM rest
awhen :: Monad m => Maybe a -> (a -> m ()) -> m ()
awhen Nothing _ = return ()
awhen (Just x) action = action x
awhenM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
awhenM test action = test >>= \t -> case t of
Just x -> action x
Nothing -> return ()
acond :: Monad m => [(Maybe a, a -> m ())] -> m ()
acond ((Nothing,_) : rest) = acond rest
acond ((Just x, action) : _) = action x
acond [] = return ()
aif :: Monad m => Maybe a -> (a -> m b) -> m b -> m b
aif Nothing _ elseclause = elseclause
aif (Just x) ifclause _ = ifclause x
aifM :: Monad m => m (Maybe a) -> (a -> m b) -> m b -> m b
aifM test ifclause elseclause = test >>= \t -> aif t ifclause elseclause
unlessM a = whenM (liftM not $ a)
ncond [] = return ()
ncond ((test , action) : rest) = if not test then action else ncond rest
ncondM :: Monad m => [(m Bool, m ())] -> m ()
ncondM [] = return ()
ncondM ((test , action) : rest) = test >>= \t -> if not t then action else ncondM rest
(&&^) = liftM2 (&&)
(||^) = liftM2 (||)
(>>?) = when
infixl 1 >>?
(>>!) = unless
infixl 1 >>!
(>>=>>!) = unlessM
infixl 1 >>=>>!
(>>=?) = awhen
infixl 1 >>=?
(>>=>>?) = whenM
infixl 1 >>=>>?
(>>=>>=?) = awhenM
infixl 1 >>=>>=?
{-# SPECIALIZE whileM :: IO Bool -> IO () -> IO () #-}
whileM :: (Monad m) => m Bool -> m () -> m ()
whileM mb m = do b <- mb ; when b (m >> whileM mb m)
{-# SPECIALIZE untilM :: IO Bool -> IO () -> IO () #-}
untilM :: (Monad m) => m Bool -> m () -> m ()
untilM mb m = do b <- mb ; unless b (m >> untilM mb m)
{-# INLINE return' #-}
return' :: (Monad m) => a -> m a
return' x = return $! x
infixr 8 `returning`
{-# INLINE returning #-}
returning :: (Monad m) => (a -> m b) -> (a -> m a)
f `returning` x = f x >> return x
{-# INLINE maybeMP #-}
maybeMP :: (MonadPlus m) => Maybe a -> m a
maybeMP = maybe mzero return
{-# RULES "maybeMP/id" maybeMP = id #-}