-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Generalized booleans and numbers
--   
--   Some classes for generalized boolean operations. Starting with 0.1.0,
--   this package uses type families. Up to version 0.0.2, it used MPTCs
--   with functional dependencies. My thanks to Andy Gill for suggesting
--   &amp; helping with the change. Thanks also to Alex Horsman for
--   Data.Boolean.Overload and to Jan Bracker for Data.Boolean.Numbers.
--   
--   Copyright 2009-2013 Conal Elliott; BSD3 license.
@package Boolean
@version 0.2.4


-- | Some classes for generalized boolean operations.
--   
--   In this design, for if-then-else, equality and inequality tests, the
--   boolean type depends on the value type.
--   
--   I also tried using a unary type constructor class. The class doesn't
--   work for regular booleans, so generality is lost. Also, we'd probably
--   have to wire class constraints in like: <tt>(==*) :: Eq a =&gt; f Bool
--   -&gt; f a -&gt; f a -&gt; f a</tt>, which disallows situations needing
--   additional constraints, e.g., Show.
--   
--   Starting with 0.1.0, this package uses type families. Up to version
--   0.0.2, it used MPTCs with functional dependencies. My thanks to Andy
--   Gill for suggesting &amp; helping with the change.
module Data.Boolean

-- | Generalized boolean class
class Boolean b
true, false :: Boolean b => b
true, false :: Boolean b => b
notB :: Boolean b => b -> b
(&&*, ||*) :: Boolean b => b -> b -> b
(&&*, ||*) :: Boolean b => b -> b -> b

-- | <a>BooleanOf</a> computed the boolean analog of a specific type.

-- | Types with conditionals
class Boolean (BooleanOf a) => IfB a
ifB :: (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a

-- | Expression-lifted conditional with condition last
boolean :: (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a

-- | Point-wise conditional
cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a

-- | Generalized cropping, filling in <a>mempty</a> where the test yields
--   false.
crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a

-- | Types with equality. Minimum definition: '(==*)'.
class Boolean (BooleanOf a) => EqB a where u /=* v = notB (u ==* v)
(==*, /=*) :: (EqB a, bool ~ BooleanOf a) => a -> a -> bool
(==*, /=*) :: (EqB a, bool ~ BooleanOf a) => a -> a -> bool

-- | Types with inequality. Minimum definition: '(&lt;*)'.
class Boolean (BooleanOf a) => OrdB a where u >* v = v <* u u >=* v = notB (u <* v) u <=* v = v >=* u
(<*, <=*, >*, >=*) :: (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<*, <=*, >*, >=*) :: (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<*, <=*, >*, >=*) :: (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
(<*, <=*, >*, >=*) :: (OrdB a, bool ~ BooleanOf a) => a -> a -> bool

-- | Variant of <a>min</a> using <a>ifB</a> and '(&lt;=*)'
minB :: (IfB a, OrdB a) => a -> a -> a

-- | Variant of <a>max</a> using <a>ifB</a> and '(&gt;=*)'
maxB :: (IfB a, OrdB a) => a -> a -> a

-- | Variant of <a>min</a> and <a>max</a> using <a>ifB</a> and '(&lt;=*)'
sort2B :: (IfB a, OrdB a) => (a, a) -> (a, a)

-- | A generalized replacement for guards and chained ifs.
guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool, b)] -> b -> b

-- | A generalized version of a case like control structure.
caseB :: (IfB b, bool ~ BooleanOf b) => a -> [(a -> bool, b)] -> b -> b
instance Data.Boolean.Boolean GHC.Types.Bool
instance Data.Boolean.IfB GHC.Types.Int
instance Data.Boolean.EqB GHC.Types.Int
instance Data.Boolean.OrdB GHC.Types.Int
instance Data.Boolean.IfB GHC.Integer.Type.Integer
instance Data.Boolean.EqB GHC.Integer.Type.Integer
instance Data.Boolean.OrdB GHC.Integer.Type.Integer
instance Data.Boolean.IfB GHC.Types.Float
instance Data.Boolean.EqB GHC.Types.Float
instance Data.Boolean.OrdB GHC.Types.Float
instance Data.Boolean.IfB GHC.Types.Double
instance Data.Boolean.EqB GHC.Types.Double
instance Data.Boolean.OrdB GHC.Types.Double
instance Data.Boolean.IfB GHC.Types.Bool
instance Data.Boolean.EqB GHC.Types.Bool
instance Data.Boolean.OrdB GHC.Types.Bool
instance Data.Boolean.IfB GHC.Types.Char
instance Data.Boolean.EqB GHC.Types.Char
instance Data.Boolean.OrdB GHC.Types.Char
instance (Data.Boolean.Boolean (Data.Boolean.BooleanOf a), Data.Boolean.BooleanOf a ~ GHC.Types.Bool) => Data.Boolean.IfB [a]
instance (bool ~ Data.Boolean.BooleanOf p, bool ~ Data.Boolean.BooleanOf q, Data.Boolean.IfB p, Data.Boolean.IfB q) => Data.Boolean.IfB (p, q)
instance (bool ~ Data.Boolean.BooleanOf p, bool ~ Data.Boolean.BooleanOf q, bool ~ Data.Boolean.BooleanOf r, Data.Boolean.IfB p, Data.Boolean.IfB q, Data.Boolean.IfB r) => Data.Boolean.IfB (p, q, r)
instance (bool ~ Data.Boolean.BooleanOf p, bool ~ Data.Boolean.BooleanOf q, bool ~ Data.Boolean.BooleanOf r, bool ~ Data.Boolean.BooleanOf s, Data.Boolean.IfB p, Data.Boolean.IfB q, Data.Boolean.IfB r, Data.Boolean.IfB s) => Data.Boolean.IfB (p, q, r, s)
instance Data.Boolean.Boolean bool => Data.Boolean.Boolean (z -> bool)
instance Data.Boolean.IfB a => Data.Boolean.IfB (z -> a)
instance Data.Boolean.EqB a => Data.Boolean.EqB (z -> a)
instance Data.Boolean.OrdB a => Data.Boolean.OrdB (z -> a)


-- | A generalized version of the class hirarchy for numbers. All functions
--   that would break a potential deep embedding are removed or generalized
--   to support deep embeddings.
--   
--   The class hierarchy for numeric types keeps as close as possible to
--   the <tt>Prelude</tt> hierarchy. A great part of the default
--   implementation and comments are copied and adopted from
--   <tt>Prelude</tt>.
module Data.Boolean.Numbers

-- | An extension of <a>Num</a> that supplies the integer type of a given
--   number type and a way to create that number from the integer.
class Num a => NumB a where type IntegerOf a where {
    type family IntegerOf a;
}

-- | Construct the number from the associated integer.
fromIntegerB :: NumB a => IntegerOf a -> a

-- | A deep embedded version of <a>Integral</a>. Integral numbers,
--   supporting integer division.
--   
--   Minimal complete definition is either <a>quotRem</a> and <a>divMod</a>
--   or the other four functions. Besides that <a>toIntegerB</a> always has
--   to be implemented.
class (NumB a, OrdB a) => IntegralB a where quot = fst .: quotRem rem = snd .: quotRem div = fst .: divMod mod = snd .: divMod quotRem = quot ## rem divMod = div ## mod

-- | Integer division truncated towards zero.
quot :: IntegralB a => a -> a -> a

-- | Integer reminder, satisfying: <tt>(x <a>quot</a> y) * y + (x
--   <a>rem</a> y) == x</tt>
rem :: IntegralB a => a -> a -> a

-- | Integer division truncated toward negative infinity.
div :: IntegralB a => a -> a -> a

-- | Integer modulus, satisfying: <tt>(x <a>div</a> y) * y + (x <a>mod</a>
--   y) == x</tt>
mod :: IntegralB a => a -> a -> a

-- | Simultaneous <a>quot</a> and <a>rem</a>.
quotRem :: IntegralB a => a -> a -> (a, a)

-- | Simultaneous <a>div</a> and <a>mod</a>.
divMod :: IntegralB a => a -> a -> (a, a)

-- | Create a integer from this integral.
toIntegerB :: IntegralB a => a -> IntegerOf a

-- | Deep embedded version of <a>RealFloat</a>. Extracting components of
--   fractions.
--   
--   Minimal complete definition: <a>properFraction</a>, <a>round</a>,
--   <a>floor</a> and <a>ceiling</a>.
class (NumB a, OrdB a, Fractional a) => RealFracB a where truncate = fst . properFraction

-- | The function <a>properFraction</a> takes a real fractional number
--   <tt>x</tt> and returns a pair <tt>(n,f)</tt> such that <tt>x =
--   n+f</tt>, and:
--   
--   <ul>
--   <li><tt>n</tt> is an integral number with the same sign as <tt>x</tt>;
--   and</li>
--   <li><tt>f</tt> is a fraction with the same type and sign as
--   <tt>x</tt>, and with absolute value less than <tt>1</tt>.</li>
--   </ul>
--   
--   The default definitions of the <a>ceiling</a>, <a>floor</a>,
--   <a>truncate</a> and <a>round</a> functions are in terms of
--   <a>properFraction</a>.
properFraction :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> (b, a)

-- | <tt><a>truncate</a> x</tt> returns the integer nearest <tt>x</tt>
--   between zero and <tt>x</tt>
truncate :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b

-- | <tt><a>round</a> x</tt> returns the nearest integer to <tt>x</tt>; the
--   even integer if <tt>x</tt> is equidistant between two integers
round :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b

-- | <tt><a>ceiling</a> x</tt> returns the least integer not less than
--   <tt>x</tt>
ceiling :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b

-- | <tt><a>floor</a> x</tt> returns the greatest integer not greater than
--   <tt>x</tt>.
floor :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b

-- | Deep embedded version of <a>RealFloat</a>. Efficient,
--   machine-independent access to the components of a floating-point
--   number.
--   
--   A complete definition has to define all functions.
class (Boolean (BooleanOf a), RealFracB a, Floating a) => RealFloatB a

-- | <a>true</a> if the argument is an IEEE "not-a-number" (NaN) value.
isNaN :: RealFloatB a => a -> BooleanOf a

-- | <a>true</a> if the argument is an IEEE infinity or negative infinity.
isInfinite :: RealFloatB a => a -> BooleanOf a

-- | <a>true</a> if the argument is an IEEE negative zero.
isNegativeZero :: RealFloatB a => a -> BooleanOf a

-- | <a>true</a> if the argument is an IEEE floating point number.
isIEEE :: RealFloatB a => a -> BooleanOf a

-- | a version of arctangent taking two real floating-point arguments. For
--   real floating <tt>x</tt> and <tt>y</tt>, <tt><a>atan2</a> y x</tt>
--   computes the angle (from the positive x-axis) of the vector from the
--   origin to the point <tt>(x,y)</tt>. <tt><a>atan2</a> y x</tt> returns
--   a value in the range [<tt>-pi</tt>, <tt>pi</tt>]. It follows the
--   Common Lisp semantics for the origin when signed zeroes are supported.
--   <tt><a>atan2</a> y 1</tt>, with <tt>y</tt> in a type that is
--   <a>RealFloatB</a>, should return the same value as <tt><a>atan</a>
--   y</tt>.
atan2 :: RealFloatB a => a -> a -> a

-- | Variant of <a>even</a> for generalized booleans.
evenB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a

-- | Variant of <a>odd</a> for generalized booleans.
oddB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a

-- | Variant of <a>fromIntegral</a> for generalized booleans.
fromIntegralB :: (IntegerOf a ~ IntegerOf b, IntegralB a, NumB b) => a -> b
instance Data.Boolean.Numbers.NumB GHC.Types.Int
instance Data.Boolean.Numbers.NumB GHC.Integer.Type.Integer
instance Data.Boolean.Numbers.NumB GHC.Types.Float
instance Data.Boolean.Numbers.NumB GHC.Types.Double
instance Data.Boolean.Numbers.IntegralB GHC.Types.Int
instance Data.Boolean.Numbers.IntegralB GHC.Integer.Type.Integer
instance Data.Boolean.Numbers.RealFracB GHC.Types.Float
instance Data.Boolean.Numbers.RealFloatB GHC.Types.Float
instance Data.Boolean.Numbers.RealFracB GHC.Types.Double
instance Data.Boolean.Numbers.RealFloatB GHC.Types.Double


-- | Author : Alex Horsman (aninhumer) Maintainer : conal@conal.net
--   Stability : experimental
--   
--   Definitions of Prelude function names in terms of their corresponding
--   Data.Boolean generalised implementation. This can then be used as part
--   of a partial or complete Prelude replacement.
--   
--   Also exports ifThenElse for use with RebindableSyntax.
module Data.Boolean.Overload
(&&) :: Boolean a => a -> a -> a
infixr 3 &&
(||) :: Boolean a => a -> a -> a
infixr 2 ||
not :: Boolean a => a -> a
ifThenElse :: IfB a => BooleanOf a -> a -> a -> a
(==) :: EqB a => a -> a -> BooleanOf a
infix 4 ==
(/=) :: EqB a => a -> a -> BooleanOf a
infix 4 /=
(<) :: OrdB a => a -> a -> BooleanOf a
infix 4 <
(>) :: OrdB a => a -> a -> BooleanOf a
infix 4 >
(<=) :: OrdB a => a -> a -> BooleanOf a
infix 4 <=
(>=) :: OrdB a => a -> a -> BooleanOf a
infix 4 >=
min :: (IfB a, OrdB a) => a -> a -> a
max :: (IfB a, OrdB a) => a -> a -> a
