-- |A convenient set of useful conditional operators. module Control.Cond ( -- * Simple conditional operators if', (??), bool -- * Higher-order conditional , select -- * Lisp-style conditional operators , cond, condPlus -- * Lifted conditional and boolean operators , ifM, (<||>), (<&&>), notM, condM, condPlusM -- * Lifted guard and when , guardM, whenM, unlessM -- * Monadic looping conditionals , whileM, untilM, while1M, until1M ) where import Control.Monad. -- -- Note that after importing "Control.Monad.Instances", 'select' becomes a -- special case of 'ifM'. (<&&>) #-} -- |Lifted boolean negation. notM :: Monad m => m Bool -> m Bool notM = liftM not {-# INLINE notM #-} -- |) -- |a variant of 'Control.Monad.when' with a monadic predicate. whenM :: Monad m => m Bool -> m () -> m () whenM p m = ifM p m (return ()) {-# INLINE whenM #-} -- |a variant of 'Control.Monad.unless' with a monadic predicate. unlessM :: Monad m => m Bool -> m () -> m () unlessM p m = ifM (notM p) m (return ()) {-# INLINE unlessM #-} -- |a variant of 'Control.Monad.guard' with a monadic predicate. guardM :: MonadPlus m => m Bool -> m () guardM = (guard =<<) {-# INLINE guardM #-} -- |A monadic while loop. whileM :: Monad m => m Bool -> m a -> m () whileM p m = whenM p (m >> whileM p m) -- |A monadic while loop with a negated conditional. untilM :: Monad m => m Bool -> m a -> m () untilM p = whileM (notM p) {-# INLINE untilM #-} -- |A monadic do-while loop. The monadic action is guaranteed to be executed -- once. Because of this, we can also return the result of the last execution -- of the loop. while1M :: Monad m => m Bool -> m a -> m a while1M p m = do a <- m ifM p (while1M p m) (return a) -- |A negated do-while loop. until1M :: Monad m => m Bool -> m a -> m a until1M p = while1M (notM p) {-# INLINE until1M #-}