-- | This module provides some convenient functions for dealing with Booleans. -- -- The most important one being 'bool', a function that can be used in place of -- the build-in @if then else@-syntax. module Data.Bool.Extras ( -- * Main function bool -- * Other functions , mwhen , whenA , whenC , whenM -- * Morphisms , BoolAlgebra , cata , ana ) where import Control.Arrow import Control.Category (Category) import qualified Control.Category as Cat import Control.Monad import Data.Bool import Data.Monoid -- | Defines the fold over a boolean value. -- -- Returns its first argument when applied to `False', -- returns its second argument when applied to `True'. -- -- Comparable to the `maybe' or `either' functions for their respective data -- types. bool :: a -> a -> Bool -> a bool x _ False = x bool _ y True = y -- Expressed in terms of `cata': -- bool = curry cata -- | Boolean operation for monoids. -- -- Returns its first argument when applied to `True', -- returns `mempty' when applied to `False'. mwhen :: (Monoid a) => a -> Bool -> a mwhen = bool mempty -- | Boolean operation for arrows. -- -- Returns its first argument when applied to `True', -- returns `returnA' when applied to `False'. whenA :: Arrow a => a b b -> Bool -> a b b whenA = bool returnA -- | Boolean operation for categories. -- -- Returns its first argument when applied to `True', -- returns @Control.Category.@`Cat.id' when applied to `False'. whenC :: Category cat => cat b b -> Bool -> cat b b whenC = bool Cat.id -- | Boolean operation for monads. -- -- Returns its first argument when applied to `True', -- returns @Control.Category.@`Cat.id' when applied to `False'. -- -- @Control.Monad.@`when' can be expressed in terms of `whenM', like so: -- -- > when :: Monad m => Bool -> m () -> m () -- > when b m = (const m `whenM` b) () whenM :: Monad m => (b -> m b) -> Bool -> (b -> m b) whenM = bool return -- Alternative implementation using Kleisli arrows: -- whenM m = runKleisli . whenC (Kleisli m) {- -- Functions that are also possible, but we haven't found an explicit need for whenP :: MonadPlus m => a -> Bool -> m a whenP = bool mzero . return () :: Applicative f => (a -> f a) -> Bool -> (a -> f a) () = bool pure -} -- | Algebra for Bool data type. -- -- The first field of the pair represents the `False' value, -- the second field represents the `True' value. type BoolAlgebra r = (r, r) -- | Catamorphism for booleans. cata :: BoolAlgebra r -> Bool -> r cata (x, _) False = x cata (_, y) True = y -- | Anamorphism for booleans. ana :: (b -> Bool) -> b -> Bool ana f b = f b