{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Data.Algebra.Boolean.FreeBoolean (
FreeBoolean(..),
module Data.Algebra.Boolean.CoBoolean
) where
import Data.Typeable (Typeable)
import Data.Foldable (Foldable)
import Control.DeepSeq (NFData(rnf))
import Data.Algebra.Boolean.CoBoolean
import Data.Algebra.Boolean.Negable hiding (not)
import qualified Data.Algebra.Boolean.Negable as Negable
import Prelude hiding ((||),(&&),not,any,all)
import Data.Algebra.Boolean
data FreeBoolean a = FBValue a
| FBTrue
| FBFalse
| FBNot (FreeBoolean a)
| FBAnd (FreeBoolean a) (FreeBoolean a)
| FBOr (FreeBoolean a) (FreeBoolean a)
deriving (Eq, Ord, Show, Read, Functor, Foldable, Typeable)
instance CoBoolean1 FreeBoolean where
toBooleanWith f (FBValue x) = f x
toBooleanWith _ FBTrue = true
toBooleanWith _ FBFalse = false
toBooleanWith f (FBNot x) = not $ toBooleanWith f x
toBooleanWith f (FBOr a b) = toBooleanWith f a || toBooleanWith f b
toBooleanWith f (FBAnd a b) = toBooleanWith f a && toBooleanWith f b
instance CoBoolean a => CoBoolean (FreeBoolean a) where
toBoolean = toBooleanWith toBoolean
instance Negable (FreeBoolean a) where
not = FBNot
instance Boolean (FreeBoolean a) where
true = FBTrue
false = FBFalse
(||) = FBOr
(&&) = FBAnd
not = FBNot
instance NFData a => NFData (FreeBoolean a) where
rnf (FBValue a) = rnf a
rnf (FBNot a) = rnf a
rnf (FBAnd a b) = rnf a `seq` rnf b
rnf (FBOr a b) = rnf a `seq` rnf b
rnf FBTrue = ()
rnf FBFalse = ()