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 +15/−0
- cond.cabal +27/−6
- src/Data/Algebra/Boolean.hs +203/−47
+ 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