{- |
Module: Data.Bool.Class
Description: Generalizations of 'Bool'
Copyright: ⓒ 2022 Anselm Schüler
License: MIT
-}

module Data.Bool.Class (
  Boolean(..),
  BooleanIf(..),
  boolean
) where

-- | Generalization of boolean operators
class Boolean b where
  false :: b
  true :: b
  (&&*) :: b -> b -> b
  (||*) :: b -> b -> b
  notB :: b -> b

instance Boolean Bool where
  false :: Bool
false = Bool
False
  true :: Bool
true = Bool
True
  &&* :: Bool -> Bool -> Bool
(&&*) = Bool -> Bool -> Bool
(&&)
  ||* :: Bool -> Bool -> Bool
(||*) = Bool -> Bool -> Bool
(||)
  notB :: Bool -> Bool
notB = Bool -> Bool
not

instance Boolean b => Boolean (a -> b) where
  false :: a -> b
false a
_ = b
forall b. Boolean b => b
false
  true :: a -> b
true a
_ = b
forall b. Boolean b => b
true
  &&* :: (a -> b) -> (a -> b) -> a -> b
(&&*) a -> b
f a -> b
g a
x = a -> b
f a
x b -> b -> b
forall b. Boolean b => b -> b -> b
&&* a -> b
g a
x
  ||* :: (a -> b) -> (a -> b) -> a -> b
(||*) a -> b
f a -> b
g a
x = a -> b
f a
x b -> b -> b
forall b. Boolean b => b -> b -> b
||* a -> b
g a
x
  notB :: (a -> b) -> a -> b
notB a -> b
f a
x = b -> b
forall b. Boolean b => b -> b
notB (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
x

-- | 'Boolean's that can be evaluated
class Boolean b => BooleanIf b where
  bIf :: b -> a -> a -> a

instance BooleanIf Bool where
  bIf :: Bool -> a -> a -> a
bIf Bool
a a
b a
c = if Bool
a then a
b else a
c

-- | Generalization of 'Data.Bool.bool' using 'bIf'
boolean :: BooleanIf b => a -> a -> b -> a
boolean :: a -> a -> b -> a
boolean a
a a
b b
c = b -> a -> a -> a
forall b a. BooleanIf b => b -> a -> a -> a
bIf b
c a
a a
b