Skip to content

Commit

Permalink
documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
aristidb committed Oct 14, 2010
1 parent b477895 commit abd0ba8
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions Control/Shortcircuit.hs
@@ -1,8 +1,19 @@
{- |
Copyright : 2010 Aristid Breitkreuz
License : BSD3
Stability : experimental
Portability : portable
Short-circuit evaluation.
-}

module Control.Shortcircuit
(
-- * Type classes
HasFalse(..)
, HasTrue(..)
, Shortcircuit(..)
-- * Short circuit tests
, isFalse
, if'
, unless'
Expand All @@ -11,6 +22,7 @@ module Control.Shortcircuit
, (&&)
, firstTrueOf
, lastFalseOf
-- * Monadic short circuits
, orM
, andM
, firstTrueOfM
Expand All @@ -23,50 +35,70 @@ import Control.Monad.Instances ()
import Data.Maybe
import Prelude hiding ((||), (&&))

-- | Types with a defined false value.
class HasFalse a where
-- | A false value for this type.
-- If 'Shortcircuit' @a@ holds, @isTrue false == False@ must hold.
false :: a

-- | Types with a defined true value.
class HasTrue a where
-- | A true value for this type.
-- If 'Shortcircuit' @a@ holds, @isTrue true == True@ must hold.
true :: a

-- | Types that support short circuits.
class Shortcircuit a where
-- | Whether the value is true-like (i.e. not false-like).
isTrue :: a -> Bool

-- | Whether the value is false-like (i.e. not true-like).
isFalse :: (Shortcircuit a) => a -> Bool
isFalse = not . isTrue

-- | @if then else@ generalised to 'Shortcircuit'.
if' :: (Shortcircuit a) => a -> b -> b -> b
if' x a b | isTrue x = a
| otherwise = b

-- | The opposite of 'if''.
unless' :: (Shortcircuit a) => a -> b -> b -> b
unless' x a b | isFalse x = a
| otherwise = b

-- | Like 'if'', but with different argument order, allowing infix use.
(??) :: (Shortcircuit a) => b -> b -> a -> b
a ?? b = \x -> if' x a b

-- | 'Prelude.||' generalised to 'Shortcircuit'.
(||) :: (Shortcircuit a) => a -> a -> a
(||) = join if'

-- | 'Prelude.&&' generalised to 'Shortcircuit'.
(&&) :: (Shortcircuit a) => a -> a -> a
(&&) = join unless'

-- | Returns the first true-ish value from a list, or 'false'.
firstTrueOf :: (Shortcircuit a, HasFalse a) => [a] -> a
firstTrueOf = foldr (||) false

-- | Returns the last false-ish value from a list, or 'true'.
lastFalseOf :: (Shortcircuit a, HasTrue a) => [a] -> a
lastFalseOf = foldr (&&) true

-- | Short-circuit two actions, performing the second only if the first returned a false-ish value.
orM :: (Monad m, Shortcircuit a) => m a -> m a -> m a
orM a b = a >>= \x -> (return x ?? b) x

-- | Short-circuit two actions, performing the second only if the first returned a true-ish value.
andM :: (Monad m, Shortcircuit a) => m a -> m a -> m a
andM a b = a >>= \x -> (b ?? return x) x

-- | Short-circuit a list of actions, performing only until a true-ish value is found, or the list exhausted.
firstTrueOfM :: (Monad m, Shortcircuit a, HasFalse a) => [m a] -> m a
firstTrueOfM = foldr orM (return false)

-- | Short-circuit a list of actions, performing only until a false-ish value is found, or the list exhausted.
lastFalseOfM :: (Monad m, Shortcircuit a, HasTrue a) => [m a] -> m a
lastFalseOfM = foldr andM (return true)

Expand Down

0 comments on commit abd0ba8

Please sign in to comment.