{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies,
UndecidableInstances, ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies, FlexibleContexts, CPP #-}
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
module Data.Boolean
( Boolean(..), BooleanOf, IfB(..)
, boolean, cond, crop
, EqB(..), OrdB(..)
, minB, maxB, sort2B
, guardedB, caseB
) where
#if MIN_VERSION_base(4,8,0)
import Prelude hiding ((<*))
#endif
import Data.Monoid (Monoid,mempty)
import Control.Applicative (Applicative(pure),liftA2,liftA3)
infixr 3 &&*
infixr 2 ||*
class Boolean b where
true, false :: b
notB :: b -> b
(&&*), (||*) :: b -> b -> b
instance Boolean Bool where
true :: Bool
true = Bool
True
false :: Bool
false = Bool
False
notB :: Bool -> Bool
notB = Bool -> Bool
not
&&* :: Bool -> Bool -> Bool
(&&*) = Bool -> Bool -> Bool
(&&)
||* :: Bool -> Bool -> Bool
(||*) = Bool -> Bool -> Bool
(||)
type family BooleanOf a
class Boolean (BooleanOf a) => IfB a where
ifB :: (bool ~ BooleanOf a) => bool -> a -> a -> a
boolean :: (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a
boolean :: a -> a -> bool -> a
boolean a
t a
e bool
bool = bool -> a -> a -> a
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
bool a
t a
e
cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
cond :: f bool -> f a -> f a -> f a
cond = (bool -> a -> a -> a) -> f bool -> f a -> f a -> f a
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 bool -> a -> a -> a
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB
crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a
crop :: f bool -> f a -> f a
crop f bool
r f a
f = f bool -> f a -> f a -> f a
forall (f :: * -> *) a bool.
(Applicative f, IfB a, bool ~ BooleanOf a) =>
f bool -> f a -> f a -> f a
cond f bool
r f a
f f a
forall a. Monoid a => a
mempty
guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool,b)] -> b -> b
guardedB :: bool -> [(bool, b)] -> b -> b
guardedB bool
_ [] b
e = b
e
guardedB bool
a ((bool
c,b
b):[(bool, b)]
l) b
e = bool -> b -> b -> b
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
c b
b (bool -> [(bool, b)] -> b -> b
forall b bool.
(IfB b, bool ~ BooleanOf b) =>
bool -> [(bool, b)] -> b -> b
guardedB bool
a [(bool, b)]
l b
e)
caseB :: (IfB b, bool ~ BooleanOf b) => a -> [(a -> bool, b)] -> b -> b
caseB :: a -> [(a -> bool, b)] -> b -> b
caseB a
_ [] b
e = b
e
caseB a
x ((a -> bool
p,b
b):[(a -> bool, b)]
l) b
e = bool -> b -> b -> b
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a -> bool
p a
x) b
b (a -> [(a -> bool, b)] -> b -> b
forall b bool a.
(IfB b, bool ~ BooleanOf b) =>
a -> [(a -> bool, b)] -> b -> b
caseB a
x [(a -> bool, b)]
l b
e)
infix 4 ==*, /=*
class Boolean (BooleanOf a) => EqB a where
(==*), (/=*) :: (bool ~ BooleanOf a) => a -> a -> bool
a
u /=* a
v = bool -> bool
forall b. Boolean b => b -> b
notB (a
u a -> a -> bool
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
==* a
v)
infix 4 <*, <=*, >=*, >*
class Boolean (BooleanOf a) => OrdB a where
(<*), (<=*), (>*), (>=*) :: (bool ~ BooleanOf a) => a -> a -> bool
a
u >* a
v = a
v a -> a -> bool
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<* a
u
a
u >=* a
v = bool -> bool
forall b. Boolean b => b -> b
notB (a
u a -> a -> bool
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<* a
v)
a
u <=* a
v = a
v a -> a -> bool
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
>=* a
u
minB :: (IfB a, OrdB a) => a -> a -> a
a
u minB :: a -> a -> a
`minB` a
v = BooleanOf a -> a -> a -> a
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u a -> a -> BooleanOf a
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<=* a
v) a
u a
v
maxB :: (IfB a, OrdB a) => a -> a -> a
a
u maxB :: a -> a -> a
`maxB` a
v = BooleanOf a -> a -> a -> a
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u a -> a -> BooleanOf a
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
>=* a
v) a
u a
v
sort2B :: (IfB a, OrdB a) => (a,a) -> (a,a)
sort2B :: (a, a) -> (a, a)
sort2B (a
u,a
v) = BooleanOf a -> (a, a) -> (a, a) -> (a, a)
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u a -> a -> BooleanOf a
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<=* a
v) (a
u,a
v) (a
v,a
u)
ife :: Bool -> a -> a -> a
ife :: Bool -> a -> a -> a
ife Bool
c a
t a
e = if Bool
c then a
t else a
e
#define SimpleInstances(Ty) \
instance IfB (Ty) where { ifB = ife } ;\
instance EqB (Ty) where { (==*) = (==) ; (/=*) = (/=) } ;\
instance OrdB (Ty) where { (<*) = (<) ; (<=*) = (<=) }
#define SimpleTy(Ty) \
type instance BooleanOf (Ty) = Bool ;\
SimpleInstances(Ty)
SimpleTy(Int)
SimpleTy(Integer)
SimpleTy(Float)
SimpleTy(Double)
SimpleTy(Bool)
SimpleTy(Char)
type instance BooleanOf [a] = BooleanOf a
type instance BooleanOf (a,b) = BooleanOf a
type instance BooleanOf (a,b,c) = BooleanOf a
type instance BooleanOf (a,b,c,d) = BooleanOf a
type instance BooleanOf (z -> a) = z -> BooleanOf a
instance (Boolean (BooleanOf a),BooleanOf a ~ Bool) => IfB [a] where { ifB :: bool -> [a] -> [a] -> [a]
ifB = bool -> [a] -> [a] -> [a]
forall a. Bool -> a -> a -> a
ife }
instance (bool ~ BooleanOf p, bool ~ BooleanOf q
,IfB p, IfB q) => IfB (p,q) where
ifB :: bool -> (p, q) -> (p, q) -> (p, q)
ifB bool
w (p
p,q
q) (p
p',q
q') = (bool -> p -> p -> p
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', bool -> q -> q -> q
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w q
q q
q')
instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r
,IfB p, IfB q, IfB r)
=> IfB (p,q,r) where
ifB :: bool -> (p, q, r) -> (p, q, r) -> (p, q, r)
ifB bool
w (p
p,q
q,r
r) (p
p',q
q',r
r') = (bool -> p -> p -> p
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', bool -> q -> q -> q
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w q
q q
q', bool -> r -> r -> r
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w r
r r
r')
instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r, bool ~ BooleanOf s
,IfB p, IfB q, IfB r, IfB s) => IfB (p,q,r,s) where
ifB :: bool -> (p, q, r, s) -> (p, q, r, s) -> (p, q, r, s)
ifB bool
w (p
p,q
q,r
r,s
s) (p
p',q
q',r
r',s
s') =
(bool -> p -> p -> p
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', bool -> q -> q -> q
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w q
q q
q', bool -> r -> r -> r
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w r
r r
r', bool -> s -> s -> s
forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w s
s s
s')
instance Boolean bool => Boolean (z -> bool) where
true :: z -> bool
true = bool -> z -> bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure bool
forall b. Boolean b => b
true
false :: z -> bool
false = bool -> z -> bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure bool
forall b. Boolean b => b
false
notB :: (z -> bool) -> z -> bool
notB = (bool -> bool) -> (z -> bool) -> z -> bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap bool -> bool
forall b. Boolean b => b -> b
notB
&&* :: (z -> bool) -> (z -> bool) -> z -> bool
(&&*) = (bool -> bool -> bool) -> (z -> bool) -> (z -> bool) -> z -> bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 bool -> bool -> bool
forall b. Boolean b => b -> b -> b
(&&*)
||* :: (z -> bool) -> (z -> bool) -> z -> bool
(||*) = (bool -> bool -> bool) -> (z -> bool) -> (z -> bool) -> z -> bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 bool -> bool -> bool
forall b. Boolean b => b -> b -> b
(||*)
instance IfB a => IfB (z -> a) where
ifB :: bool -> (z -> a) -> (z -> a) -> z -> a
ifB = bool -> (z -> a) -> (z -> a) -> z -> a
forall (f :: * -> *) a bool.
(Applicative f, IfB a, bool ~ BooleanOf a) =>
f bool -> f a -> f a -> f a
cond
instance EqB a => EqB (z -> a) where
{ ==* :: (z -> a) -> (z -> a) -> bool
(==*) = (a -> a -> BooleanOf a) -> (z -> a) -> (z -> a) -> z -> BooleanOf a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> BooleanOf a
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
(==*) ; /=* :: (z -> a) -> (z -> a) -> bool
(/=*) = (a -> a -> BooleanOf a) -> (z -> a) -> (z -> a) -> z -> BooleanOf a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> BooleanOf a
forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
(/=*) }
instance OrdB a => OrdB (z -> a) where
{ <* :: (z -> a) -> (z -> a) -> bool
(<*) = (a -> a -> BooleanOf a) -> (z -> a) -> (z -> a) -> z -> BooleanOf a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> BooleanOf a
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<*) ; <=* :: (z -> a) -> (z -> a) -> bool
(<=*) = (a -> a -> BooleanOf a) -> (z -> a) -> (z -> a) -> z -> BooleanOf a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> BooleanOf a
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<=*) }