{-# LANGUAGE FlexibleInstances #-}
module Control.Conditional
(
ToBool(..)
, if', (??), bool
, ifM, (<||>), (<&&>), notM, xorM
, cond, condDefault, condPlus, condM, condPlusM, otherwiseM
, (?.)
, (?<>)
, select, selectM
, (?)
, (|>), (<|)
, (|>>), (<<|)
, (⊳), (⊲)
, guard, guardM, when, whenM, unless, unlessM,
) where
import Data.Algebra.Boolean
import Control.Monad hiding (guard, when, unless)
import Control.Category
import Data.Monoid
import Data.Maybe
import Prelude hiding ((.), id, (&&), (||), not)
infixr 0 <|, |>, ⊳, ⊲, ?, <<|, |>>
infixr 1 ??
infixr 2 <||>
infixr 3 <&&>
infixr 7 ?<>
infixr 9 ?.
class ToBool bool where
toBool :: bool -> Bool
instance ToBool Bool where toBool :: Bool -> Bool
toBool = forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
instance ToBool Any where toBool :: Any -> Bool
toBool = Any -> Bool
getAny
instance ToBool All where toBool :: All -> Bool
toBool = All -> Bool
getAll
instance ToBool (Dual Bool) where toBool :: Dual Bool -> Bool
toBool = forall a. Dual a -> a
getDual
if' :: ToBool bool => bool -> a -> a -> a
if' :: forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p a
t a
f = if forall bool. ToBool bool => bool -> Bool
toBool bool
p then a
t else a
f
{-# INLINE if' #-}
(??) :: ToBool bool => a -> a -> bool -> a
?? :: forall bool a. ToBool bool => a -> a -> bool -> a
(??) a
t a
f bool
p = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p a
t a
f
{-# INLINE (??) #-}
bool :: (ToBool bool) => a -> a -> bool -> a
bool :: forall bool a. ToBool bool => a -> a -> bool -> a
bool a
f a
t bool
p = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p a
t a
f
{-# INLINE bool #-}
cond :: ToBool bool => [(bool, a)] -> a
cond :: forall bool a. ToBool bool => [(bool, a)] -> a
cond [] = forall a. HasCallStack => [Char] -> a
error [Char]
"cond: no matching conditions"
cond ((bool
p,a
v):[(bool, a)]
ls) = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p a
v (forall bool a. ToBool bool => [(bool, a)] -> a
cond [(bool, a)]
ls)
condDefault :: ToBool bool => a -> [(bool, a)] -> a
condDefault :: forall bool a. ToBool bool => a -> [(bool, a)] -> a
condDefault = (forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall bool (m :: * -> *) a.
(ToBool bool, MonadPlus m) =>
[(bool, a)] -> m a
condPlus) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. a -> Maybe a -> a
(<|)
{-# INLINE condDefault #-}
condPlus :: (ToBool bool, MonadPlus m) => [(bool, a)] -> m a
condPlus :: forall bool (m :: * -> *) a.
(ToBool bool, MonadPlus m) =>
[(bool, a)] -> m a
condPlus [] = forall (m :: * -> *) a. MonadPlus m => m a
mzero
condPlus ((bool
p,a
v):[(bool, a)]
ls) = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p (forall (m :: * -> *) a. Monad m => a -> m a
return a
v) (forall bool (m :: * -> *) a.
(ToBool bool, MonadPlus m) =>
[(bool, a)] -> m a
condPlus [(bool, a)]
ls)
(?.) :: (ToBool bool, Category cat) => bool -> cat a a -> cat a a
bool
p ?. :: forall bool (cat :: * -> * -> *) a.
(ToBool bool, Category cat) =>
bool -> cat a a -> cat a a
?. cat a a
c = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p cat a a
c forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
{-# INLINE (?.) #-}
select :: ToBool bool => (a -> bool) -> (a -> b) -> (a -> b) -> (a -> b)
select :: forall bool a b.
ToBool bool =>
(a -> bool) -> (a -> b) -> (a -> b) -> a -> b
select a -> bool
p a -> b
t a -> b
f a
x = forall bool a. ToBool bool => bool -> a -> a -> a
if' (a -> bool
p a
x) (a -> b
t a
x) (a -> b
f a
x)
{-# INLINE select #-}
ifM :: (ToBool bool, Monad m) => m bool -> m a -> m a -> m a
ifM :: forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
p m a
t m a
f = m bool
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall bool a. ToBool bool => a -> a -> bool -> a
bool m a
f m a
t
{-# INLINE ifM #-}
(<||>) :: (ToBool bool, Boolean bool, Monad m) => m bool -> m bool -> m bool
<||> :: forall bool (m :: * -> *).
(ToBool bool, Boolean bool, Monad m) =>
m bool -> m bool -> m bool
(<||>) m bool
t m bool
f = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
t (forall (m :: * -> *) a. Monad m => a -> m a
return forall b. Boolean b => b
true) m bool
f
{-# INLINE (<||>) #-}
(<&&>) :: (ToBool bool, Boolean bool, Monad m) => m bool -> m bool -> m bool
<&&> :: forall bool (m :: * -> *).
(ToBool bool, Boolean bool, Monad m) =>
m bool -> m bool -> m bool
(<&&>) m bool
t m bool
f = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
t m bool
f (forall (m :: * -> *) a. Monad m => a -> m a
return forall b. Boolean b => b
false)
{-# INLINE (<&&>) #-}
notM :: (Boolean bool, Monad m) => m bool -> m bool
notM :: forall bool (m :: * -> *).
(Boolean bool, Monad m) =>
m bool -> m bool
notM = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall b. Boolean b => b -> b
not
{-# INLINE notM #-}
xorM :: (Boolean bool, Monad m) => m bool -> m bool -> m bool
xorM :: forall bool (m :: * -> *).
(Boolean bool, Monad m) =>
m bool -> m bool -> m bool
xorM = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall b. Boolean b => b -> b -> b
xor
condM :: (ToBool bool, Monad m) => [(m bool, m a)] -> m a
condM :: forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
[(m bool, m a)] -> m a
condM [] = forall a. HasCallStack => [Char] -> a
error [Char]
"condM: no matching conditions"
condM ((m bool
p, m a
v):[(m bool, m a)]
ls) = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
p m a
v (forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
[(m bool, m a)] -> m a
condM [(m bool, m a)]
ls)
condPlusM :: (ToBool bool, MonadPlus m) => [(m bool, m a)] -> m a
condPlusM :: forall bool (m :: * -> *) a.
(ToBool bool, MonadPlus m) =>
[(m bool, m a)] -> m a
condPlusM [] = forall (m :: * -> *) a. MonadPlus m => m a
mzero
condPlusM ((m bool
p, m a
v):[(m bool, m a)]
ls) = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
p m a
v (forall bool (m :: * -> *) a.
(ToBool bool, MonadPlus m) =>
[(m bool, m a)] -> m a
condPlusM [(m bool, m a)]
ls)
otherwiseM :: (Boolean bool, Monad m) => m bool
otherwiseM :: forall bool (m :: * -> *). (Boolean bool, Monad m) => m bool
otherwiseM = forall (m :: * -> *) a. Monad m => a -> m a
return forall b. Boolean b => b
true
guard :: (ToBool bool, MonadPlus m) => bool -> m ()
guard :: forall bool (m :: * -> *).
(ToBool bool, MonadPlus m) =>
bool -> m ()
guard bool
p = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p (forall (m :: * -> *) a. Monad m => a -> m a
return ()) forall (m :: * -> *) a. MonadPlus m => m a
mzero
{-# INLINE guard #-}
when :: (ToBool bool, Monad m) => bool -> m () -> m ()
when :: forall bool (m :: * -> *).
(ToBool bool, Monad m) =>
bool -> m () -> m ()
when bool
p m ()
m = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p m ()
m (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINE when #-}
unless :: (Boolean bool, ToBool bool, Monad m) => bool -> m() -> m()
unless :: forall bool (m :: * -> *).
(Boolean bool, ToBool bool, Monad m) =>
bool -> m () -> m ()
unless bool
p m ()
m = forall bool a. ToBool bool => bool -> a -> a -> a
if' (forall b. Boolean b => b -> b
not bool
p) m ()
m (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINE unless #-}
whenM :: (ToBool bool, Monad m) => m bool -> m () -> m ()
whenM :: forall bool (m :: * -> *).
(ToBool bool, Monad m) =>
m bool -> m () -> m ()
whenM m bool
p m ()
m = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
p m ()
m (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINE whenM #-}
unlessM :: (ToBool bool, Boolean bool, Monad m) => m bool -> m () -> m ()
unlessM :: forall bool (m :: * -> *).
(ToBool bool, Boolean bool, Monad m) =>
m bool -> m () -> m ()
unlessM m bool
p m ()
m = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM (forall bool (m :: * -> *).
(Boolean bool, Monad m) =>
m bool -> m bool
notM m bool
p) m ()
m (forall (m :: * -> *) a. Monad m => a -> m a
return ())
{-# INLINE unlessM #-}
guardM :: (ToBool bool, MonadPlus m) => m bool -> m ()
guardM :: forall bool (m :: * -> *).
(ToBool bool, MonadPlus m) =>
m bool -> m ()
guardM = (forall bool (m :: * -> *).
(ToBool bool, MonadPlus m) =>
bool -> m ()
guard forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<)
{-# INLINE guardM #-}
selectM :: (ToBool bool, Monad m) =>
(a -> m bool) -> (a -> m b) -> (a -> m b) -> (a -> m b)
selectM :: forall bool (m :: * -> *) a b.
(ToBool bool, Monad m) =>
(a -> m bool) -> (a -> m b) -> (a -> m b) -> a -> m b
selectM a -> m bool
p a -> m b
t a -> m b
f a
x = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM (a -> m bool
p a
x) (a -> m b
t a
x) (a -> m b
f a
x)
{-# INLINE selectM #-}
(?<>) :: (ToBool bool, Monoid a) => bool -> a -> a
bool
p ?<> :: forall bool a. (ToBool bool, Monoid a) => bool -> a -> a
?<> a
m = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p a
m forall a. Monoid a => a
mempty
{-# INLINE (?<>) #-}
(?) :: b -> (b -> a) -> a
b
p ? :: forall b a. b -> (b -> a) -> a
? b -> a
f = b -> a
f b
p
{-# INLINE (?) #-}
(|>) :: ToBool bool => bool -> a -> Maybe a
bool
p |> :: forall bool a. ToBool bool => bool -> a -> Maybe a
|> a
v = forall bool a. ToBool bool => bool -> a -> a -> a
if' bool
p forall a. Maybe a
Nothing (forall a. a -> Maybe a
Just a
v)
{-# INLINE (|>) #-}
(<|) :: a -> Maybe a -> a
a
t <| :: forall a. a -> Maybe a -> a
<| Maybe a
Nothing = a
t
a
_ <| Just a
f = a
f
{-# INLINE (<|) #-}
(|>>) :: (ToBool bool, Monad m) => m bool -> m a -> m (Maybe a)
m bool
p |>> :: forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m (Maybe a)
|>> m a
v = forall bool (m :: * -> *) a.
(ToBool bool, Monad m) =>
m bool -> m a -> m a -> m a
ifM m bool
p (forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing) (forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. a -> Maybe a
Just m a
v)
{-# INLINE (|>>) #-}
(<<|) :: Monad m => m a -> m (Maybe a) -> m a
m a
v <<| :: forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
<<| m (Maybe a)
mv = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> Maybe a -> a
fromMaybe m a
v m (Maybe a)
mv
{-# INLINE (<<|) #-}
(⊲) :: a -> Maybe a -> a
⊲ :: forall a. a -> Maybe a -> a
(⊲) = forall a. a -> Maybe a -> a
(<|)
(⊳) :: ToBool bool => bool -> a -> Maybe a
⊳ :: forall bool a. ToBool bool => bool -> a -> Maybe a
(⊳) = forall bool a. ToBool bool => bool -> a -> Maybe a
(|>)