----------------------------------------------------------------------------- -- | -- Module : Control.Bool -- Copyright : (C) 2013 Fumiaki Kinoshita -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Fumiaki Kinoshita -- Stability : experimental -- Portability : portable -- -- Useful combinators for boolean expressions ---------------------------------------------------------------------------- module Control.Bool ( -- * A pure combinator bool , ifThenElse -- * Applicative combinators , notF , (<||>) , (<&&>) , aguard , aguard' -- * Monadic combinators , notM , (<|=>) , (<&=>) , guard' , guardM' , whenM , unlessM , ifThenElseM ) where import Control.Applicative import Control.Monad import Data.Monoid infixr 3 <&&>, <&=> infixr 2 <||>, <|=> -- | @bool a b@ is a function that returns a if the argument is True, otherwise returns 'b'. bool :: a -> a -> Bool -> a bool x _ False = x bool _ y True = y {-# INLINE bool #-} -- | An argument-permuted equivalent of 'bool'. ifThenElse :: Bool -> a -> a -> a ifThenElse True x _ = x ifThenElse False _ y = y -- | A lifted 'not'. notF :: Functor f => f Bool -> f Bool notF = fmap not {-# INLINE notF #-} -- | A lifted 'not'. notM :: Monad m => m Bool -> m Bool notM = liftM not {-# INLINE notM #-} -- | A lifted ('&&'). (<&&>) :: Applicative f => f Bool -> f Bool -> f Bool (<&&>) = liftA2 (&&) {-# INLINE (<&&>) #-} -- | A lifted ('&&'), but short-circuited. (<&=>) :: Monad m => m Bool -> m Bool -> m Bool m <&=> n = do r <- m bool (return False) n r {-# INLINE (<&=>) #-} -- | A lifted ('||'). (<||>) :: Applicative f => f Bool -> f Bool -> f Bool (<||>) = liftA2 (||) {-# INLINE (<||>) #-} -- | A lifted ('||'), but short-circuited. (<|=>) :: Monad m => m Bool -> m Bool -> m Bool m <|=> n = do r <- m bool n (return True) r {-# INLINE (<|=>) #-} -- | Run the action if the given monadic condition becomes 'True'. whenM :: (Monoid a, Monad m) => m Bool -> m a -> m a whenM mp m = mp >>= bool (return mempty) m {-# INLINE whenM #-} -- | Run the action if the given monadic condition becomes 'False'. unlessM :: (Monoid a, Monad m) => m Bool -> m a -> m a unlessM mp m = mp >>= bool m (return mempty) {-# INLINE unlessM #-} ifThenElseM :: Monad m => m Bool -> m a -> m a -> m a ifThenElseM mp m n = do r <- mp if r then m else n {-# INLINE ifThenElseM #-} -- | 'guard'' b a returns a if b is True, otherwise becomes 'mzero'. guard' :: MonadPlus m => Bool -> a -> m a guard' b a = bool mzero (return a) b {-# INLINE guard' #-} -- | 'guard'' b returns the second argument if b is True, otherwise becomes mzero. guardM' :: MonadPlus m => m Bool -> a -> m a guardM' mp a = mp >>= flip guard' a {-# INLINE guardM' #-} -- | An 'Alternative' analogue of 'guard'. aguard :: Alternative m => Bool -> m () aguard = bool empty (pure ()) {-# INLINE aguard #-} -- | 'aguard'' b returns the second argument if b is True, otherwise becomes 'empty'. aguard' :: Alternative m => Bool -> a -> m a aguard' b a = bool empty (pure a) b {-# INLINE aguard' #-}