packages feed

cond 0.4.1.1 → 0.5.0

raw patch · 3 files changed

+245/−53 lines, 3 filesnew-uploaderPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Conditional: instance ToBool (Dual Bool)
- Control.Conditional: instance ToBool All
- Control.Conditional: instance ToBool Any
- Control.Conditional: instance ToBool Bool
- Data.Algebra.Boolean: getBits :: Bitwise a -> a
- Data.Algebra.Boolean: instance (Boolean x, Boolean y) => Boolean (x, y)
- Data.Algebra.Boolean: instance (Num a, Bits a) => Boolean (Bitwise a)
- Data.Algebra.Boolean: instance Bits a => Bits (Bitwise a)
- Data.Algebra.Boolean: instance Boolean (Dual Bool)
- Data.Algebra.Boolean: instance Boolean (Endo Bool)
- Data.Algebra.Boolean: instance Boolean All
- Data.Algebra.Boolean: instance Boolean Any
- Data.Algebra.Boolean: instance Boolean Bool
- Data.Algebra.Boolean: instance Bounded a => Bounded (Bitwise a)
- Data.Algebra.Boolean: instance Data a => Data (Bitwise a)
- Data.Algebra.Boolean: instance Enum a => Enum (Bitwise a)
- Data.Algebra.Boolean: instance Eq a => Eq (Bitwise a)
- Data.Algebra.Boolean: instance Integral a => Integral (Bitwise a)
- Data.Algebra.Boolean: instance Ix a => Ix (Bitwise a)
- Data.Algebra.Boolean: instance Num a => Num (Bitwise a)
- Data.Algebra.Boolean: instance Ord a => Ord (Bitwise a)
- Data.Algebra.Boolean: instance PrintfArg a => PrintfArg (Bitwise a)
- Data.Algebra.Boolean: instance Read a => Read (Bitwise a)
- Data.Algebra.Boolean: instance Real a => Real (Bitwise a)
- Data.Algebra.Boolean: instance Show a => Show (Bitwise a)
- Data.Algebra.Boolean: instance Storable a => Storable (Bitwise a)
- Data.Algebra.Boolean: instance Typeable Bitwise
+ Control.Conditional: infixr 0 ⊲
+ Control.Conditional: infixr 1 ??
+ Control.Conditional: infixr 2 <||>
+ Control.Conditional: infixr 3 <&&>
+ Control.Conditional: infixr 7 ?<>
+ Control.Conditional: infixr 9 ?.
+ Control.Conditional: instance Control.Conditional.ToBool (Data.Semigroup.Internal.Dual GHC.Types.Bool)
+ Control.Conditional: instance Control.Conditional.ToBool Data.Semigroup.Internal.All
+ Control.Conditional: instance Control.Conditional.ToBool Data.Semigroup.Internal.Any
+ Control.Conditional: instance Control.Conditional.ToBool GHC.Types.Bool
+ Data.Algebra.Boolean: AllB :: b -> AllB b
+ Data.Algebra.Boolean: AnyB :: b -> AnyB b
+ Data.Algebra.Boolean: EquivB :: b -> EquivB b
+ Data.Algebra.Boolean: Opp :: a -> Opp a
+ Data.Algebra.Boolean: XorB :: b -> XorB b
+ Data.Algebra.Boolean: [getAllB] :: AllB b -> b
+ Data.Algebra.Boolean: [getAnyB] :: AnyB b -> b
+ Data.Algebra.Boolean: [getBits] :: Bitwise a -> a
+ Data.Algebra.Boolean: [getEquivB] :: EquivB b -> b
+ Data.Algebra.Boolean: [getOpp] :: Opp a -> a
+ Data.Algebra.Boolean: [getXorB] :: XorB b -> b
+ Data.Algebra.Boolean: infixr 1 -->
+ Data.Algebra.Boolean: infixr 2 ||
+ Data.Algebra.Boolean: infixr 3 &&
+ Data.Algebra.Boolean: instance (Data.Algebra.Boolean.Boolean x, Data.Algebra.Boolean.Boolean y) => Data.Algebra.Boolean.Boolean (x, y)
+ Data.Algebra.Boolean: instance (Data.Algebra.Boolean.Boolean x, Data.Algebra.Boolean.Boolean y, Data.Algebra.Boolean.Boolean z) => Data.Algebra.Boolean.Boolean (x, y, z)
+ Data.Algebra.Boolean: instance (GHC.Num.Num a, GHC.Bits.Bits a) => Data.Algebra.Boolean.Boolean (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean ()
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean (Data.Semigroup.Internal.Dual GHC.Types.Bool)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean Data.Semigroup.Internal.All
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean Data.Semigroup.Internal.Any
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean GHC.Types.Bool
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean a => Data.Algebra.Boolean.Boolean (Data.Algebra.Boolean.Opp a)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean a => Data.Algebra.Boolean.Boolean (Data.Semigroup.Internal.Endo a)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => Data.Algebra.Boolean.Boolean (a -> b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Monoid (Data.Algebra.Boolean.AllB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Monoid (Data.Algebra.Boolean.AnyB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Monoid (Data.Algebra.Boolean.EquivB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Monoid (Data.Algebra.Boolean.XorB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Semigroup (Data.Algebra.Boolean.AllB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Semigroup (Data.Algebra.Boolean.AnyB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Semigroup (Data.Algebra.Boolean.EquivB b)
+ Data.Algebra.Boolean: instance Data.Algebra.Boolean.Boolean b => GHC.Base.Semigroup (Data.Algebra.Boolean.XorB b)
+ Data.Algebra.Boolean: instance Data.Data.Data a => Data.Data.Data (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance Foreign.Storable.Storable a => Foreign.Storable.Storable (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Bits.Bits a => GHC.Bits.Bits (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Algebra.Boolean.Opp a)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq b => GHC.Classes.Eq (Data.Algebra.Boolean.AllB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq b => GHC.Classes.Eq (Data.Algebra.Boolean.AnyB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq b => GHC.Classes.Eq (Data.Algebra.Boolean.EquivB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Eq b => GHC.Classes.Eq (Data.Algebra.Boolean.XorB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Algebra.Boolean.Opp a)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord b => GHC.Classes.Ord (Data.Algebra.Boolean.AllB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord b => GHC.Classes.Ord (Data.Algebra.Boolean.AnyB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord b => GHC.Classes.Ord (Data.Algebra.Boolean.EquivB b)
+ Data.Algebra.Boolean: instance GHC.Classes.Ord b => GHC.Classes.Ord (Data.Algebra.Boolean.XorB b)
+ Data.Algebra.Boolean: instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Enum.Enum a => GHC.Enum.Enum (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Ix.Ix a => GHC.Ix.Ix (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Num.Num a => GHC.Num.Num (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Read.Read a => GHC.Read.Read (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Real.Integral a => GHC.Real.Integral (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Real.Real a => GHC.Real.Real (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Show.Show a => GHC.Show.Show (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: instance GHC.Show.Show a => GHC.Show.Show (Data.Algebra.Boolean.Opp a)
+ Data.Algebra.Boolean: instance GHC.Show.Show b => GHC.Show.Show (Data.Algebra.Boolean.AllB b)
+ Data.Algebra.Boolean: instance GHC.Show.Show b => GHC.Show.Show (Data.Algebra.Boolean.AnyB b)
+ Data.Algebra.Boolean: instance GHC.Show.Show b => GHC.Show.Show (Data.Algebra.Boolean.EquivB b)
+ Data.Algebra.Boolean: instance GHC.Show.Show b => GHC.Show.Show (Data.Algebra.Boolean.XorB b)
+ Data.Algebra.Boolean: instance Text.Printf.PrintfArg a => Text.Printf.PrintfArg (Data.Algebra.Boolean.Bitwise a)
+ Data.Algebra.Boolean: newtype AllB b
+ Data.Algebra.Boolean: newtype AnyB b
+ Data.Algebra.Boolean: newtype EquivB b
+ Data.Algebra.Boolean: newtype Opp a
+ Data.Algebra.Boolean: newtype XorB b
- Control.Conditional: select :: ToBool bool => (a -> bool) -> (a -> b) -> (a -> b) -> (a -> b)
+ Control.Conditional: select :: ToBool bool => (a -> bool) -> (a -> b) -> (a -> b) -> a -> b
- Control.Conditional: selectM :: (ToBool bool, Monad m) => (a -> m bool) -> (a -> m b) -> (a -> m b) -> (a -> m b)
+ Control.Conditional: selectM :: (ToBool bool, Monad m) => (a -> m bool) -> (a -> m b) -> (a -> m b) -> a -> m b
- Data.Algebra.Boolean: class Boolean b where nand = not . and nor = not . or true = not false false = not true not = (<--> false) x && y = not (not x || not y) x || y = not (not x && not y) x `xor` y = (x || y) && (not (x && y)) x --> y = not x || y x <--> y = (x && y) || not (x || y) and = foldl' (&&) true or = foldl' (||) false all p = foldl' f true where f a b = a && p b any p = foldl' f false where f a b = a || p b
+ Data.Algebra.Boolean: class Boolean b

Files

+ CHANGELOG.md view
@@ -0,0 +1,15 @@+## 0.5.0++- Four monoid structures for a boolean algebra (`AnyB`, `AllB`, `XorB`, `EquivB`)+- Typeclass altered so that {or, and, nor, nand, any, all} are no longer members+- Add instances for `()` and `(a,b,c)`+- `minimal` pragma (and corresponding definition)+- The opposite Boolean algebra (exchanging `true` and `false`, `&&` and `||`, etc)+- A more general instance for `Endo`+- Tested with GHC 7.0 - 9.6+++## 0.4.2++- Add `instance Boolean b => Boolean (a -> b)`+- Tested with GHC 7.0 - 9.6
cond.cabal view
@@ -1,13 +1,13 @@+Cabal-Version: >= 1.10 Name: cond-Version: 0.4.1.1+Version: 0.5.0 Synopsis: Basic conditional and boolean operators with monadic variants. Category: Control, Logic, Monad License: BSD3 License-File: LICENSE Author: Adam Curtis-Maintainer: acurtis@spsu.edu-Homepage: https://github.com/kallisti-dev/cond-Cabal-Version: >= 1.6+Maintainer: acurtis@spsu.edu, James Cranch <j.d.cranch@sheffield.ac.uk>+Homepage: https://github.com/jcranch/cond Build-Type: Simple Description:   This library provides:@@ -23,12 +23,32 @@   .   Monadic looping constructs are not included as part of this package, since the   monad-loops package has a fairly complete collection of them already.++tested-with:+  GHC == 9.6.3+  GHC == 9.4.6+  GHC == 9.2.8+  GHC == 9.0.2+  GHC == 8.10.7+  GHC == 8.8.4+  GHC == 8.6.5+  GHC == 8.4.4+  GHC == 8.2.2+  GHC == 8.0.2+  GHC == 7.10.3+  GHC == 7.8.4+  GHC == 7.6.3+  GHC == 7.4.2+  GHC == 7.2.2+  GHC == 7.0.4+ Extra-source-files:   README.md- +  CHANGELOG.md+ source-repository head   type: git-  location: git://github.com/kallisti-dev/cond.git +  location: https://github.com/jcranch/cond.git  library   hs-source-dirs: src@@ -36,3 +56,4 @@   exposed-modules: Control.Conditional                    Data.Algebra.Boolean   build-depends: base >= 3 && < 5+  default-language: Haskell2010
src/Data/Algebra/Boolean.hs view
@@ -1,17 +1,38 @@-{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving,-             DeriveDataTypeable+{-# LANGUAGE+      CPP,+      FlexibleInstances,+      GeneralizedNewtypeDeriving,+      DeriveDataTypeable   #-}-module Data.Algebra.Boolean-       ( Boolean(..), fromBool, Bitwise(..)-       ) where+module Data.Algebra.Boolean(+  Boolean(..),+  fromBool,+  Bitwise(..),+  and,+  or,+  nand,+  nor,+  any,+  all,+  Opp(..),+  AnyB(..),+  AllB(..),+  XorB(..),+  EquivB(..),+  ) where import Data.Monoid (Any(..), All(..), Dual(..), Endo(..)) import Data.Bits (Bits, complement, (.|.), (.&.)) import qualified Data.Bits as Bits import Data.Function (on)+#if MIN_VERSION_base(4,11,0)+import Data.Semigroup (Semigroup(..), stimesIdempotentMonoid)+#elif MIN_VERSION_base(4,9,0)+#else+import Data.Monoid (Monoid(..))+#endif import Data.Typeable import Data.Data import Data.Ix-import Data.Foldable (Foldable) import qualified Data.Foldable as F import Foreign.Storable import Text.Printf@@ -23,9 +44,9 @@ infixr  3 &&  -- |A class for boolean algebras. Instances of this class are expected to obey--- all the laws of boolean algebra.+-- all the laws of [boolean algebra](https://en.wikipedia.org/wiki/Boolean_algebra_(structure)). ----- Minimal complete definition: 'true' or 'false', 'not' or '<-->', '||' or '&&'.+-- Minimal complete definition: 'true' or 'false', 'not' or ('<-->', 'false'), '||' or '&&'. class Boolean b where   -- |Truth value, defined as the top of the bounded lattice   true    :: b@@ -33,7 +54,7 @@   false   :: b   -- |Logical negation.   not     :: b -> b-  -- |Logical conjunction. (infxr 3)+  -- |Logical conjunction. (infixr 3)   (&&)    :: b -> b -> b   -- |Logical inclusive disjunction. (infixr 2)   (||)    :: b -> b -> b@@ -44,47 +65,132 @@   -- |Logical biconditional. (infixr 1)   (<-->) :: b -> b -> b -  -- | The logical conjunction of several values.-  and :: Foldable t => t b -> b--  -- | The logical disjunction of several values.-  or :: Foldable t => t b -> b--  -- | The negated logical conjunction of several values.-  ---  -- @'nand' = 'not' . 'and'@-  nand :: Foldable t => t b -> b-  nand = not . and--  -- | The logical conjunction of the mapping of a function over several values.-  all :: Foldable t => (a -> b) -> t a -> b--  -- | The logical disjunction of the mapping of a function over several values.-  any :: Foldable t => (a -> b) -> t a -> b--  -- | The negated logical disjunction of several values.-  ---  -- @'nor' = 'not' . 'or'@-  nor :: Foldable t => t b -> b-  nor = not . or+  {-# MINIMAL (false | true), (not | ((<-->), false)), ((||) | (&&)) #-}    -- Default implementations   true      = not false   false     = not true   not       = (<--> false)-  x && y = not (not x || not y)-  x || y = not (not x && not y)+  x && y    = not (not x || not y)+  x || y    = not (not x && not y)   x `xor` y = (x || y) && (not (x && y))   x --> y   = not x || y   x <--> y  = (x && y) || not (x || y)-  and       = F.foldl' (&&) true-  or        = F.foldl' (||) false-  all p     = F.foldl' f true-    where f a b = a && p b-  any p     = F.foldl' f false-    where f a b = a || p b  +-- | The logical conjunction of several values.+and :: (Boolean b, F.Foldable t) => t b -> b+and = F.foldl' (&&) true++-- | The logical disjunction of several values.+or :: (Boolean b, F.Foldable t) => t b -> b+or = F.foldl' (||) false++-- | The negated logical conjunction of several values.+--+-- @'nand' = 'not' . 'and'@+nand :: (Boolean b, F.Foldable t) => t b -> b+nand = not . and++-- | The negated logical disjunction of several values.+--+-- @'nor' = 'not' . 'or'@+nor :: (Boolean b, F.Foldable t) => t b -> b+nor = not . or++-- | The logical conjunction of the mapping of a function over several values.+all :: (Boolean b, F.Foldable t) => (a -> b) -> t a -> b+all p = F.foldl' f true+  where f a b = a && p b++-- | The logical disjunction of the mapping of a function over several values.+any :: (Boolean b, F.Foldable t) => (a -> b) -> t a -> b+any p     = F.foldl' f false+  where f a b = a || p b+++-- | A boolean algebra regarded as a monoid under disjunction+newtype AnyB b = AnyB {+  getAnyB :: b+} deriving (Eq, Ord, Show)++#if MIN_VERSION_base(4,11,0)+instance Boolean b => Semigroup (AnyB b) where+  AnyB x <> AnyB y = AnyB (x || y)+  stimes = stimesIdempotentMonoid++instance Boolean b => Monoid (AnyB b) where+  mempty = AnyB false+#else+instance Boolean b => Monoid (AnyB b) where+  mappend (AnyB x) (AnyB y) = AnyB (x || y)+  mempty = AnyB false+#endif+++-- | A boolean algebra regarded as a monoid under conjunction+newtype AllB b = AllB {+  getAllB :: b+} deriving (Eq, Ord, Show)++#if MIN_VERSION_base(4,11,0)+instance Boolean b => Semigroup (AllB b) where+  AllB x <> AllB y = AllB (x && y)+  stimes = stimesIdempotentMonoid++instance Boolean b => Monoid (AllB b) where+  mempty = AllB true+#else+instance Boolean b => Monoid (AllB b) where+  mappend (AllB x) (AllB y) = AllB (x && y)+  mempty = AllB true+#endif+++-- | `stimes` for a group of exponent 2+stimesPeriod2 :: (Monoid a, Integral n) => n -> a -> a+stimesPeriod2 n x+  | even n    = x+  | otherwise = mempty++-- | A boolean algebra regarded as a monoid under exclusive or+newtype XorB b = XorB {+  getXorB :: b+} deriving (Eq, Ord, Show)++#if MIN_VERSION_base(4,11,0)+instance Boolean b => Semigroup (XorB b) where+  XorB x <> XorB y = XorB (x `xor` y)+  stimes = stimesPeriod2++instance Boolean b => Monoid (XorB b) where+  mempty = XorB false+#else+instance Boolean b => Monoid (XorB b) where+  mappend (XorB x) (XorB y) = XorB (x `xor` y)+  mempty = XorB false+#endif+++-- | A boolean algebra regarded as a monoid under equivalence+newtype EquivB b = EquivB {+  getEquivB :: b+}  deriving (Eq, Ord, Show)++#if MIN_VERSION_base(4,11,0)+instance Boolean b => Semigroup (EquivB b) where+  EquivB x <> EquivB y = EquivB (x <--> y)+  stimes = stimesPeriod2++instance Boolean b => Monoid (EquivB b) where+  mempty = EquivB true+#else+instance Boolean b => Monoid (EquivB b) where+  mappend (EquivB x) (EquivB y) = EquivB (x <--> y)+  mempty = EquivB true+#endif++ -- |Injection from 'Bool' into a boolean algebra. fromBool :: Boolean b => Bool -> b fromBool b = if b then true else false@@ -96,11 +202,11 @@   (||) = (P.||)   not = P.not   xor = (/=)-  True  --> True  = True-  True  --> False = False-  False --> _     = True+  True  --> a = a+  False --> _ = True   (<-->) = (==) +-- | Could be done via `deriving via` from GHC8.6.1 onwards instance Boolean Any where   true                  = Any True   false                 = Any False@@ -111,6 +217,7 @@   (Any p) --> (Any q)   = Any (p --> q)   (Any p) <--> (Any q)  = Any (p <--> q) +-- | Could be done via `deriving via` from GHC8.6.1 onwards instance Boolean All where   true                  = All True   false                 = All False@@ -121,6 +228,7 @@   (All p) --> (All q)   = All (p --> q)   (All p) <--> (All q)  = All (p <--> q) +-- | Could be done via `deriving via` from GHC8.6.1 onwards instance Boolean (Dual Bool) where   true                    = Dual True   false                   = Dual False@@ -131,9 +239,36 @@   (Dual p) --> (Dual q)   = Dual (p --> q)   (Dual p) <--> (Dual q)  = Dual (p <--> q) -instance Boolean (Endo Bool) where-  true                    = Endo (const True)-  false                   = Endo (const False)+newtype Opp a = Opp { getOpp :: a }+  deriving (Eq, Ord, Show)++-- | Opposite boolean algebra: exchanges true and false, and `and` and+-- `or`, etc+instance Boolean a => Boolean (Opp a) where+  true = Opp false+  false = Opp true+  not = Opp . not . getOpp+  (&&) = (Opp .) . (||) `on` getOpp+  (||) = (Opp .) . (&&) `on` getOpp+  xor = (Opp .) . (<-->) `on` getOpp+  (<-->) = (Opp .) . xor `on` getOpp++-- | Pointwise boolean algebra.+--+instance Boolean b => Boolean (a -> b) where+  true      = const true+  false     = const false+  not p     = not . p+  p && q    = \a -> p a && q a+  p || q    = \a -> p a || q a+  p `xor` q = \a -> p a `xor` q a+  p --> q   = \a -> p a --> q a+  p <--> q  = \a -> p a <--> q a++-- | Could be done via `deriving via` from GHC8.6.1 onwards+instance Boolean a => Boolean (Endo a) where+  true                    = Endo (const true)+  false                   = Endo (const false)   not (Endo p)            = Endo (not . p)   (Endo p) && (Endo q)    = Endo (\a -> p a && q a)   (Endo p) || (Endo q)    = Endo (\a -> p a || q a)@@ -141,6 +276,16 @@   (Endo p) --> (Endo q)   = Endo (\a -> p a --> q a)   (Endo p) <--> (Endo q)  = Endo (\a -> p a <--> q a) +-- |The trivial boolean algebra+instance Boolean () where+  true = ()+  false = ()+  not _ = ()+  _ && _ = ()+  _ || _ = ()+  _ --> _ = ()+  _ <--> _ = ()+ instance (Boolean x, Boolean y) => Boolean (x, y) where   true                = (true, true)   false               = (false, false)@@ -151,6 +296,17 @@   (a, b) --> (c, d)   = (a --> c, b --> d)   (a, b) <--> (c, d)  = (a <--> c, b <--> d) +instance (Boolean x, Boolean y, Boolean z) => Boolean (x, y, z) where+  true                      = (true, true, true)+  false                     = (false, false, false)+  not (a, b, c)             = (not a, not b, not c)+  (a, b, c) && (d, e, f)    = (a && d, b && e, c && f)+  (a, b, c) || (d, e, f)    = (a || d, b || e, c || f)+  (a, b, c) `xor` (d, e, f) = (a `xor` d, b `xor` e, c `xor` f)+  (a, b, c) --> (d, e, f)   = (a --> d, b --> e, c --> f)+  (a, b, c) <--> (d, e, f)  = (a <--> d, b <--> e, c <--> f)++ -- |A newtype wrapper that derives a 'Boolean' instance from any type that is both -- a 'Bits' instance and a 'Num' instance, -- such that boolean logic operations on the 'Bitwise' wrapper correspond to@@ -171,4 +327,4 @@   (&&)   = (Bitwise .) . (.&.) `on` getBits   (||)   = (Bitwise .) . (.|.) `on` getBits   xor    = (Bitwise .) . (Bits.xor `on` getBits)-  (<-->) = xor `on` not+  (<-->) = (not .) . xor