{-# LANGUAGE
DataKinds,
PolyKinds,
TypeFamilies,
TypeInType,
TypeOperators,
UndecidableInstances #-}
module Fcf.Data.Bool
( UnBool
, type (||)
, type (&&)
, Not
, Guarded
, Guard((:=))
, Otherwise
) where
import Fcf.Core
import Fcf.Combinators (ConstFn)
import Fcf.Utils
data UnBool :: Exp a -> Exp a -> Bool -> Exp a
type instance Eval (UnBool fal tru 'False) = Eval fal
type instance Eval (UnBool fal tru 'True ) = Eval tru
infixr 2 ||
infixr 3 &&
data (||) :: Bool -> Bool -> Exp Bool
type instance Eval ('True || b) = 'True
type instance Eval (a || 'True) = 'True
type instance Eval ('False || b) = b
type instance Eval (a || 'False) = a
data (&&) :: Bool -> Bool -> Exp Bool
type instance Eval ('False && b) = 'False
type instance Eval (a && 'False) = 'False
type instance Eval ('True && b) = b
type instance Eval (a && 'True) = a
data Not :: Bool -> Exp Bool
type instance Eval (Not 'True) = 'False
type instance Eval (Not 'False) = 'True
data Guarded :: a -> [Guard (a -> Exp Bool) (Exp b)] -> Exp b
type instance Eval (Guarded x ((p ':= y) ': ys)) =
Eval (If (Eval (p x)) y (Guarded x ys))
data Guard a b = a := b
infixr 0 :=
type Otherwise = ConstFn 'True