{-# 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 :: forall a bool. (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a
boolean a
t a
e bool
bool = 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 :: forall (f :: * -> *) a bool.
(Applicative f, IfB a, bool ~ BooleanOf a) =>
f bool -> f a -> f a -> f a
cond = forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 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 :: forall (f :: * -> *) a bool.
(Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) =>
f bool -> f a -> f a
crop f bool
r f a
f = 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 forall a. Monoid a => a
mempty
guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool,b)] -> b -> b
guardedB :: forall b bool.
(IfB b, bool ~ BooleanOf b) =>
bool -> [(bool, b)] -> b -> b
guardedB bool
_ [] b
e = b
e
guardedB bool
a ((bool
c,b
b):[(bool, b)]
l) b
e = forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
c 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 :: forall b bool a.
(IfB b, bool ~ BooleanOf b) =>
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 = forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a -> bool
p a
x) 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 = forall b. Boolean b => b -> b
notB (a
u 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 forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<* a
u
a
u >=* a
v = forall b. Boolean b => b -> b
notB (a
u forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
<* a
v)
a
u <=* a
v = a
v forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
>=* a
u
minB :: (IfB a, OrdB a) => a -> a -> a
a
u minB :: forall a. (IfB a, OrdB a) => a -> a -> a
`minB` a
v = forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u 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 :: forall a. (IfB a, OrdB a) => a -> a -> a
`maxB` a
v = forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u 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 :: forall a. (IfB a, OrdB a) => (a, a) -> (a, a)
sort2B (a
u,a
v) = forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB (a
u 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 :: forall a. 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 :: forall bool. (bool ~ BooleanOf [a]) => bool -> [a] -> [a] -> [a]
ifB = forall a. Bool -> a -> a -> a
ife }
instance (bool ~ BooleanOf p, bool ~ BooleanOf q
,IfB p, IfB q) => IfB (p,q) where
ifB :: forall bool.
(bool ~ BooleanOf (p, q)) =>
bool -> (p, q) -> (p, q) -> (p, q)
ifB bool
w (p
p,q
q) (p
p',q
q') = (forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', 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 :: forall bool.
(bool ~ BooleanOf (p, q, r)) =>
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') = (forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w q
q q
q', 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 :: forall bool.
(bool ~ BooleanOf (p, q, r, s)) =>
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') =
(forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w p
p p
p', forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w q
q q
q', forall a bool. (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
ifB bool
w r
r r
r', 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 = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b. Boolean b => b
true
false :: z -> bool
false = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b. Boolean b => b
false
notB :: (z -> bool) -> z -> bool
notB = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b. Boolean b => b -> b
notB
&&* :: (z -> bool) -> (z -> bool) -> z -> bool
(&&*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall b. Boolean b => b -> b -> b
(&&*)
||* :: (z -> bool) -> (z -> bool) -> z -> bool
(||*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall b. Boolean b => b -> b -> b
(||*)
instance IfB a => IfB (z -> a) where
ifB :: forall bool.
(bool ~ BooleanOf (z -> a)) =>
bool -> (z -> a) -> (z -> a) -> z -> a
ifB = 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
{ ==* :: forall bool.
(bool ~ BooleanOf (z -> a)) =>
(z -> a) -> (z -> a) -> bool
(==*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
(==*) ; /=* :: forall bool.
(bool ~ BooleanOf (z -> a)) =>
(z -> a) -> (z -> a) -> bool
(/=*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a bool. (EqB a, bool ~ BooleanOf a) => a -> a -> bool
(/=*) }
instance OrdB a => OrdB (z -> a) where
{ <* :: forall bool.
(bool ~ BooleanOf (z -> a)) =>
(z -> a) -> (z -> a) -> bool
(<*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<*) ; <=* :: forall bool.
(bool ~ BooleanOf (z -> a)) =>
(z -> a) -> (z -> a) -> bool
(<=*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<=*) }