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


-- | A numeric prelude
--   
--   A numeric prelude, providing a clean structure for numbers and
--   operations that combine them.
@package numhask
@version 0.1.4.0


-- | A magma heirarchy for addition. The basic magma structure is repeated
--   and prefixed with 'Additive-'.
module NumHask.Algebra.Additive

-- | <a>plus</a> is used as the operator for the additive magma to
--   distinguish from <a>+</a> which, by convention, implies commutativity
--   
--   <pre>
--   ∀ a,b ∈ A: a `plus` b ∈ A
--   </pre>
--   
--   law is true by construction in Haskell
class AdditiveMagma a
plus :: AdditiveMagma a => a -> a -> a

-- | Unital magma for addition.
--   
--   <pre>
--   zero `plus` a == a
--   a `plus` zero == a
--   </pre>
class AdditiveMagma a => AdditiveUnital a
zero :: AdditiveUnital a => a

-- | Associative magma for addition.
--   
--   <pre>
--   (a `plus` b) `plus` c == a `plus` (b `plus` c)
--   </pre>
class AdditiveMagma a => AdditiveAssociative a

-- | Commutative magma for addition.
--   
--   <pre>
--   a `plus` b == b `plus` a
--   </pre>
class AdditiveMagma a => AdditiveCommutative a

-- | Invertible magma for addition.
--   
--   <pre>
--   ∀ a ∈ A: negate a ∈ A
--   </pre>
--   
--   law is true by construction in Haskell
class AdditiveMagma a => AdditiveInvertible a
negate :: AdditiveInvertible a => a -> a

-- | Idempotent magma for addition.
--   
--   <pre>
--   a `plus` a == a
--   </pre>
class AdditiveMagma a => AdditiveIdempotent a

-- | sum definition avoiding a clash with the Sum monoid in base
sum :: (Additive a, Foldable f) => f a -> a

-- | Additive is commutative, unital and associative under addition
--   
--   <pre>
--   zero + a == a
--   a + zero == a
--   (a + b) + c == a + (b + c)
--   a + b == b + a
--   </pre>
class (AdditiveCommutative a, AdditiveUnital a, AdditiveAssociative a) => Additive a
(+) :: Additive a => a -> a -> a

-- | Non-commutative right minus
--   
--   <pre>
--   a `plus` negate a = zero
--   </pre>
class (AdditiveUnital a, AdditiveAssociative a, AdditiveInvertible a) => AdditiveRightCancellative a
(-~) :: AdditiveRightCancellative a => a -> a -> a

-- | Non-commutative left minus
--   
--   <pre>
--   negate a `plus` a = zero
--   </pre>
class (AdditiveUnital a, AdditiveAssociative a, AdditiveInvertible a) => AdditiveLeftCancellative a
(~-) :: AdditiveLeftCancellative a => a -> a -> a

-- | Minus (<a>-</a>) is reserved for where both the left and right
--   cancellative laws hold. This then implies that the AdditiveGroup is
--   also Abelian.
--   
--   Syntactic unary negation - substituting "negate a" for "-a" in code -
--   is hard-coded in the language to assume a Num instance. So, for
--   example, using ''-a = zero - a' for the second rule below doesn't
--   work.
--   
--   <pre>
--   a - a = zero
--   negate a = zero - a
--   negate a + a = zero
--   a + negate a = zero
--   </pre>
class (Additive a, AdditiveInvertible a) => AdditiveGroup a
(-) :: AdditiveGroup a => a -> a -> a
instance NumHask.Algebra.Additive.AdditiveGroup GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveGroup GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveGroup GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveGroup GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveGroup a => NumHask.Algebra.Additive.AdditiveGroup (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.Additive GHC.Types.Double
instance NumHask.Algebra.Additive.Additive GHC.Types.Float
instance NumHask.Algebra.Additive.Additive GHC.Types.Int
instance NumHask.Algebra.Additive.Additive GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.Additive GHC.Types.Bool
instance NumHask.Algebra.Additive.Additive a => NumHask.Algebra.Additive.Additive (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.AdditiveIdempotent GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveInvertible GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveInvertible GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveInvertible GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveInvertible GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveInvertible GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveInvertible a => NumHask.Algebra.Additive.AdditiveInvertible (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.AdditiveCommutative GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveCommutative GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveCommutative GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveCommutative GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveCommutative GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveCommutative a => NumHask.Algebra.Additive.AdditiveCommutative (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.AdditiveAssociative GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveAssociative GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveAssociative GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveAssociative GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveAssociative GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveAssociative a => NumHask.Algebra.Additive.AdditiveAssociative (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.AdditiveUnital GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveUnital GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveUnital GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveUnital GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveUnital GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveUnital a => NumHask.Algebra.Additive.AdditiveUnital (Data.Complex.Complex a)
instance NumHask.Algebra.Additive.AdditiveMagma GHC.Types.Double
instance NumHask.Algebra.Additive.AdditiveMagma GHC.Types.Float
instance NumHask.Algebra.Additive.AdditiveMagma GHC.Types.Int
instance NumHask.Algebra.Additive.AdditiveMagma GHC.Integer.Type.Integer
instance NumHask.Algebra.Additive.AdditiveMagma GHC.Types.Bool
instance NumHask.Algebra.Additive.AdditiveMagma a => NumHask.Algebra.Additive.AdditiveMagma (Data.Complex.Complex a)


-- | Bootstrapping the number system.
--   
--   This heirarchy is repeated for the Additive and Multiplicative
--   structures, in order to achieve class separation, so these classes are
--   not used in the main numerical classes.
module NumHask.Algebra.Magma

-- | A <a>Magma</a> is a tuple (T,⊕) consisting of
--   
--   <ul>
--   <li>a type a, and</li>
--   <li>a function (⊕) :: T -&gt; T -&gt; T</li>
--   </ul>
--   
--   The mathematical laws for a magma are:
--   
--   <ul>
--   <li>⊕ is defined for all possible pairs of type T, and</li>
--   <li>⊕ is closed in the set of all possible values of type T</li>
--   </ul>
--   
--   or, more tersly,
--   
--   <pre>
--   ∀ a, b ∈ T: a ⊕ b ∈ T
--   </pre>
--   
--   These laws are true by construction in haskell: the type signature of
--   <tt>magma</tt> and the above mathematical laws are synonyms.
class Magma a
(⊕) :: Magma a => a -> a -> a

-- | A Unital Magma
--   
--   <pre>
--   unit ⊕ a = a
--   a ⊕ unit = a
--   </pre>
class Magma a => Unital a
unit :: Unital a => a

-- | An Associative Magma
--   
--   <pre>
--   (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)
--   </pre>
class Magma a => Associative a

-- | A Commutative Magma
--   
--   <pre>
--   a ⊕ b = b ⊕ a
--   </pre>
class Magma a => Commutative a

-- | An Invertible Magma
--   
--   <pre>
--   ∀ a ∈ T: inv a ∈ T
--   </pre>
--   
--   law is true by construction in Haskell
class Magma a => Invertible a
inv :: Invertible a => a -> a

-- | An Idempotent Magma
--   
--   <pre>
--   a ⊕ a = a
--   </pre>
class Magma a => Idempotent a

-- | A Monoidal Magma is associative and unital.
class (Associative a, Unital a) => Monoidal a

-- | A CMonoidal Magma is commutative, associative and unital.
class (Commutative a, Associative a, Unital a) => CMonoidal a

-- | A Loop is unital and invertible
class (Unital a, Invertible a) => Loop a

-- | A Group is associative, unital and invertible
class (Associative a, Unital a, Invertible a) => Group a

-- | see <a>http://chris-taylor.github.io/blog/2013/02/25/xor-trick/</a>
groupSwap :: (Group a) => (a, a) -> (a, a)

-- | An Abelian Group is associative, unital, invertible and commutative
class (Associative a, Unital a, Invertible a, Commutative a) => Abelian a


-- | A magma heirarchy for multiplication. The basic magma structure is
--   repeated and prefixed with 'Multiplicative-'.
module NumHask.Algebra.Multiplicative

-- | <a>times</a> is used as the operator for the multiplicative magam to
--   distinguish from <a>*</a> which, by convention, implies commutativity
--   
--   <pre>
--   ∀ a,b ∈ A: a `times` b ∈ A
--   </pre>
--   
--   law is true by construction in Haskell
class MultiplicativeMagma a
times :: MultiplicativeMagma a => a -> a -> a

-- | Unital magma for multiplication.
--   
--   <pre>
--   one `times` a == a
--   a `times` one == a
--   </pre>
class MultiplicativeMagma a => MultiplicativeUnital a
one :: MultiplicativeUnital a => a

-- | Associative magma for multiplication.
--   
--   <pre>
--   (a `times` b) `times` c == a `times` (b `times` c)
--   </pre>
class MultiplicativeMagma a => MultiplicativeAssociative a

-- | Commutative magma for multiplication.
--   
--   <pre>
--   a `times` b == b `times` a
--   </pre>
class MultiplicativeMagma a => MultiplicativeCommutative a

-- | Invertible magma for multiplication.
--   
--   <pre>
--   ∀ a ∈ A: recip a ∈ A
--   </pre>
--   
--   law is true by construction in Haskell
class MultiplicativeMagma a => MultiplicativeInvertible a
recip :: MultiplicativeInvertible a => a -> a

-- | product definition avoiding a clash with the Product monoid in base
product :: (Multiplicative a, Foldable f) => f a -> a

-- | Multiplicative is commutative, associative and unital under
--   multiplication
--   
--   <pre>
--   one * a == a
--   a * one == a
--   (a * b) * c == a * (b * c)
--   a * b == b * a
--   </pre>
class (MultiplicativeCommutative a, MultiplicativeUnital a, MultiplicativeAssociative a) => Multiplicative a
(*) :: Multiplicative a => a -> a -> a

-- | Non-commutative right divide
--   
--   <pre>
--   a `times` recip a = one
--   </pre>
class (MultiplicativeUnital a, MultiplicativeAssociative a, MultiplicativeInvertible a) => MultiplicativeRightCancellative a
(/~) :: MultiplicativeRightCancellative a => a -> a -> a

-- | Non-commutative left divide
--   
--   <pre>
--   recip a `times` a = one
--   </pre>
class (MultiplicativeUnital a, MultiplicativeAssociative a, MultiplicativeInvertible a) => MultiplicativeLeftCancellative a
(~/) :: MultiplicativeLeftCancellative a => a -> a -> a

-- | Divide (<a>/</a>) is reserved for where both the left and right
--   cancellative laws hold. This then implies that the MultiplicativeGroup
--   is also Abelian.
--   
--   <pre>
--   a / a = one
--   recip a = one / a
--   recip a * a = one
--   a * recip a = one
--   </pre>
class (Multiplicative a, MultiplicativeInvertible a) => MultiplicativeGroup a
(/) :: MultiplicativeGroup a => a -> a -> a
instance NumHask.Algebra.Multiplicative.MultiplicativeGroup GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeGroup GHC.Types.Float
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.MultiplicativeGroup a) => NumHask.Algebra.Multiplicative.MultiplicativeGroup (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.Multiplicative GHC.Types.Double
instance NumHask.Algebra.Multiplicative.Multiplicative GHC.Types.Float
instance NumHask.Algebra.Multiplicative.Multiplicative GHC.Types.Int
instance NumHask.Algebra.Multiplicative.Multiplicative GHC.Integer.Type.Integer
instance NumHask.Algebra.Multiplicative.Multiplicative GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.Multiplicative a) => NumHask.Algebra.Multiplicative.Multiplicative (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.MultiplicativeIdempotent GHC.Types.Bool
instance NumHask.Algebra.Multiplicative.MultiplicativeInvertible GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeInvertible GHC.Types.Float
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.MultiplicativeInvertible a) => NumHask.Algebra.Multiplicative.MultiplicativeInvertible (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.MultiplicativeCommutative GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeCommutative GHC.Types.Float
instance NumHask.Algebra.Multiplicative.MultiplicativeCommutative GHC.Types.Int
instance NumHask.Algebra.Multiplicative.MultiplicativeCommutative GHC.Integer.Type.Integer
instance NumHask.Algebra.Multiplicative.MultiplicativeCommutative GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.MultiplicativeCommutative a) => NumHask.Algebra.Multiplicative.MultiplicativeCommutative (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.MultiplicativeAssociative GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeAssociative GHC.Types.Float
instance NumHask.Algebra.Multiplicative.MultiplicativeAssociative GHC.Types.Int
instance NumHask.Algebra.Multiplicative.MultiplicativeAssociative GHC.Integer.Type.Integer
instance NumHask.Algebra.Multiplicative.MultiplicativeAssociative GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.MultiplicativeAssociative a) => NumHask.Algebra.Multiplicative.MultiplicativeAssociative (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.MultiplicativeUnital GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeUnital GHC.Types.Float
instance NumHask.Algebra.Multiplicative.MultiplicativeUnital GHC.Types.Int
instance NumHask.Algebra.Multiplicative.MultiplicativeUnital GHC.Integer.Type.Integer
instance NumHask.Algebra.Multiplicative.MultiplicativeUnital GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveUnital a, NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Multiplicative.MultiplicativeUnital a) => NumHask.Algebra.Multiplicative.MultiplicativeUnital (Data.Complex.Complex a)
instance NumHask.Algebra.Multiplicative.MultiplicativeMagma GHC.Types.Double
instance NumHask.Algebra.Multiplicative.MultiplicativeMagma GHC.Types.Float
instance NumHask.Algebra.Multiplicative.MultiplicativeMagma GHC.Types.Int
instance NumHask.Algebra.Multiplicative.MultiplicativeMagma GHC.Integer.Type.Integer
instance NumHask.Algebra.Multiplicative.MultiplicativeMagma GHC.Types.Bool
instance (NumHask.Algebra.Multiplicative.MultiplicativeMagma a, NumHask.Algebra.Additive.AdditiveGroup a) => NumHask.Algebra.Multiplicative.MultiplicativeMagma (Data.Complex.Complex a)


-- | <a>Distribution</a> avoids a name clash with <a>Distributive</a>
module NumHask.Algebra.Distribution

-- | Distribution (and annihilation) laws
--   
--   <pre>
--   a * (b + c) == a * b + a * c
--   (a + b) * c == a * c + b * c
--   a * zero == zero
--   zero * a == zero
--   </pre>
class (Additive a, MultiplicativeMagma a) => Distribution a
instance NumHask.Algebra.Distribution.Distribution GHC.Types.Double
instance NumHask.Algebra.Distribution.Distribution GHC.Types.Float
instance NumHask.Algebra.Distribution.Distribution GHC.Types.Int
instance NumHask.Algebra.Distribution.Distribution GHC.Integer.Type.Integer
instance NumHask.Algebra.Distribution.Distribution GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Distribution.Distribution a) => NumHask.Algebra.Distribution.Distribution (Data.Complex.Complex a)


-- | Element-by-element operation for <tt>Representable</tt>s
module NumHask.Algebra.Basis

-- | element by element addition
--   
--   <pre>
--   (a .+. b) .+. c == a .+. (b .+. c)
--   zero .+. a = a
--   a .+. zero = a
--   a .+. b == b .+. a
--   </pre>
class (Additive a) => AdditiveBasis m a
(.+.) :: AdditiveBasis m a => m a -> m a -> m a

-- | element by element subtraction
--   
--   <pre>
--   a .-. a = singleton zero
--   </pre>
class (AdditiveGroup a) => AdditiveGroupBasis m a
(.-.) :: AdditiveGroupBasis m a => m a -> m a -> m a

-- | element by element multiplication
--   
--   <pre>
--   (a .*. b) .*. c == a .*. (b .*. c)
--   singleton one .*. a = a
--   a .*. singelton one = a
--   a .*. b == b .*. a
--   </pre>
class (Multiplicative a) => MultiplicativeBasis m a
(.*.) :: MultiplicativeBasis m a => m a -> m a -> m a

-- | element by element division
--   
--   <pre>
--   a ./. a == singleton one
--   </pre>
class (MultiplicativeGroup a) => MultiplicativeGroupBasis m a
(./.) :: MultiplicativeGroupBasis m a => m a -> m a -> m a


-- | Ring classes. A distinguishment is made between Rings and Commutative
--   Rings.
module NumHask.Algebra.Ring

-- | Semiring
class (MultiplicativeAssociative a, MultiplicativeUnital a, Distribution a) => Semiring a

-- | Ring a summary of the laws inherited from the ring super-classes
--   
--   <pre>
--   zero + a == a
--   a + zero == a
--   (a + b) + c == a + (b + c)
--   a + b == b + a
--   a - a = zero
--   negate a = zero - a
--   negate a + a = zero
--   a + negate a = zero
--   one `times` a == a
--   a `times` one == a
--   (a `times` b) `times` c == a `times` (b `times` c)
--   a `times` (b + c) == a `times` b + a `times` c
--   (a + b) `times` c == a `times` c + b `times` c
--   a `times` zero == zero
--   zero `times` a == zero
--   </pre>
class (Semiring a, AdditiveGroup a) => Ring a

-- | CRing is a Ring with Multiplicative Commutation. It arises often due
--   to <a>*</a> being defined as a multiplicative commutative operation.
class (Multiplicative a, Ring a) => CRing a

-- | StarSemiring
--   
--   <pre>
--   star a = one + a `times` star a
--   </pre>
class (Semiring a) => StarSemiring a
star :: StarSemiring a => a -> a
plus' :: StarSemiring a => a -> a

-- | KleeneAlgebra
--   
--   <pre>
--   a `times` x + x = a ==&gt; star a `times` x + x = x
--   x `times` a + x = a ==&gt; x `times` star a + x = x
--   </pre>
class (StarSemiring a, AdditiveIdempotent a) => KleeneAlgebra a
instance NumHask.Algebra.Ring.CRing GHC.Types.Double
instance NumHask.Algebra.Ring.CRing GHC.Types.Float
instance NumHask.Algebra.Ring.CRing GHC.Types.Int
instance NumHask.Algebra.Ring.CRing GHC.Integer.Type.Integer
instance NumHask.Algebra.Ring.CRing a => NumHask.Algebra.Ring.CRing (Data.Complex.Complex a)
instance NumHask.Algebra.Ring.Ring GHC.Types.Double
instance NumHask.Algebra.Ring.Ring GHC.Types.Float
instance NumHask.Algebra.Ring.Ring GHC.Types.Int
instance NumHask.Algebra.Ring.Ring GHC.Integer.Type.Integer
instance NumHask.Algebra.Ring.Ring a => NumHask.Algebra.Ring.Ring (Data.Complex.Complex a)
instance NumHask.Algebra.Ring.Semiring GHC.Types.Double
instance NumHask.Algebra.Ring.Semiring GHC.Types.Float
instance NumHask.Algebra.Ring.Semiring GHC.Types.Int
instance NumHask.Algebra.Ring.Semiring GHC.Integer.Type.Integer
instance NumHask.Algebra.Ring.Semiring GHC.Types.Bool
instance (NumHask.Algebra.Additive.AdditiveGroup a, NumHask.Algebra.Ring.Semiring a) => NumHask.Algebra.Ring.Semiring (Data.Complex.Complex a)


-- | Integral classes
module NumHask.Algebra.Integral

-- | Integral laws
--   
--   <pre>
--   b == zero || b * (a `div` b) + (a `mod` b) == a
--   </pre>
class (Ring a) => Integral a
div :: Integral a => a -> a -> a
mod :: Integral a => a -> a -> a
divMod :: Integral a => a -> a -> (a, a)

-- | toInteger is kept separate from Integral to help with compatability
--   issues.
class ToInteger a
toInteger :: ToInteger a => a -> Integer

-- | fromInteger is the most problematic of the <tt>Num</tt> class
--   operators. Particularly heinous, it is assumed that any number type
--   can be constructed from an Integer, so that the broad classes of
--   objects that are composed of multiple elements is avoided in haskell.
class FromInteger a
fromInteger :: FromInteger a => Integer -> a

-- | coercion of <a>Integral</a>s
--   
--   <pre>
--   fromIntegral a == a
--   </pre>
fromIntegral :: (ToInteger a, FromInteger b) => a -> b
instance NumHask.Algebra.Integral.FromInteger GHC.Types.Double
instance NumHask.Algebra.Integral.FromInteger GHC.Types.Float
instance NumHask.Algebra.Integral.FromInteger GHC.Types.Int
instance NumHask.Algebra.Integral.FromInteger GHC.Integer.Type.Integer
instance NumHask.Algebra.Integral.ToInteger GHC.Types.Int
instance NumHask.Algebra.Integral.ToInteger GHC.Integer.Type.Integer
instance NumHask.Algebra.Integral.Integral GHC.Types.Int
instance NumHask.Algebra.Integral.Integral GHC.Integer.Type.Integer


-- | Field classes
module NumHask.Algebra.Field

-- | A Semifield is a Field without Commutative Multiplication.
class (MultiplicativeInvertible a, Ring a) => Semifield a

-- | A Field is a Ring plus additive invertible and multiplicative
--   invertible operations.
--   
--   A summary of the rules inherited from super-classes of Field
--   
--   <pre>
--   zero + a == a
--   a + zero == a
--   (a + b) + c == a + (b + c)
--   a + b == b + a
--   a - a = zero
--   negate a = zero - a
--   negate a + a = zero
--   a + negate a = zero
--   one * a == a
--   a * one == a
--   (a * b) * c == a * (b * c)
--   a * (b + c) == a * b + a * c
--   (a + b) * c == a * c + b * c
--   a * zero == zero
--   zero * a == zero
--   a * b == b * a
--   a / a = one
--   recip a = one / a
--   recip a * a = one
--   a * recip a = one
--   </pre>
class (AdditiveGroup a, MultiplicativeGroup a, Ring a) => Field a

-- | A hyperbolic field class
--   
--   <pre>
--   sqrt . (**2) == identity
--   log . exp == identity
--   for +ive b, a != 0,1: a ** logBase a b ≈ b
--   </pre>
class (Field a) => ExpField a
exp :: ExpField a => a -> a
log :: ExpField a => a -> a
logBase :: ExpField a => a -> a -> a
(**) :: ExpField a => a -> a -> a
sqrt :: ExpField a => a -> a

-- | quotient fields explode constraints if they allow for polymorphic
--   integral types
--   
--   <pre>
--   a - one &lt; floor a &lt;= a &lt;= ceiling a &lt; a + one
--   round a == floor (a + one/(one+one))
--   </pre>
class (Field a) => QuotientField a
round :: QuotientField a => a -> Integer
ceiling :: QuotientField a => a -> Integer
floor :: QuotientField a => a -> Integer
(^^) :: QuotientField a => a -> Integer -> a

-- | A bounded field includes the concepts of infinity and NaN, thus moving
--   away from error throwing.
--   
--   <pre>
--   one / zero + infinity == infinity
--   infinity + a == infinity
--   isNaN (infinity - infinity)
--   isNaN (infinity / infinity)
--   isNaN (nan + a)
--   zero / zero != nan
--   </pre>
--   
--   Note the tricky law that, although nan is assigned to zero/zero, they
--   are never-the-less not equal. A committee decided this.
class (Field a) => BoundedField a
maxBound :: BoundedField a => a
minBound :: BoundedField a => a
nan :: BoundedField a => a
isNaN :: BoundedField a => a -> Bool

-- | prints as <tt>Infinity</tt>
infinity :: BoundedField a => a

-- | prints as `-Infinity`
neginfinity :: BoundedField a => a

-- | Trigonometric Field
class (Ord a, Field a) => TrigField a
pi :: TrigField a => a
sin :: TrigField a => a -> a
cos :: TrigField a => a -> a
tan :: TrigField a => a -> a
asin :: TrigField a => a -> a
acos :: TrigField a => a -> a
atan :: TrigField a => a -> a
sinh :: TrigField a => a -> a
cosh :: TrigField a => a -> a
tanh :: TrigField a => a -> a
asinh :: TrigField a => a -> a
acosh :: TrigField a => a -> a
atanh :: TrigField a => a -> a
atan2 :: TrigField a => a -> a -> a
instance (NumHask.Algebra.Field.TrigField a, NumHask.Algebra.Field.ExpField a) => NumHask.Algebra.Field.ExpField (Data.Complex.Complex a)
instance NumHask.Algebra.Field.TrigField GHC.Types.Double
instance NumHask.Algebra.Field.TrigField GHC.Types.Float
instance NumHask.Algebra.Field.BoundedField GHC.Types.Float
instance NumHask.Algebra.Field.BoundedField GHC.Types.Double
instance NumHask.Algebra.Field.BoundedField a => NumHask.Algebra.Field.BoundedField (Data.Complex.Complex a)
instance NumHask.Algebra.Field.QuotientField GHC.Types.Float
instance NumHask.Algebra.Field.QuotientField GHC.Types.Double
instance NumHask.Algebra.Field.ExpField GHC.Types.Double
instance NumHask.Algebra.Field.ExpField GHC.Types.Float
instance NumHask.Algebra.Field.Field GHC.Types.Double
instance NumHask.Algebra.Field.Field GHC.Types.Float
instance NumHask.Algebra.Field.Field a => NumHask.Algebra.Field.Field (Data.Complex.Complex a)
instance NumHask.Algebra.Field.Semifield GHC.Types.Double
instance NumHask.Algebra.Field.Semifield GHC.Types.Float
instance NumHask.Algebra.Field.Semifield a => NumHask.Algebra.Field.Semifield (Data.Complex.Complex a)


-- | Metric classes
module NumHask.Algebra.Metric

-- | <tt>signum</tt> from base is not an operator replicated in numhask,
--   being such a very silly name, and preferred is the much more obvious
--   <a>sign</a>. Compare with <tt>Norm</tt> and <tt>Banach</tt> where
--   there is a change in codomain
--   
--   <pre>
--   abs a * sign a == a
--   </pre>
--   
--   Generalising this class tends towards size and direction (abs is the
--   size on the one-dim number line of a vector with its tail at zero, and
--   sign is the direction, right?).
class (MultiplicativeUnital a) => Signed a
sign :: Signed a => a -> a
abs :: Signed a => a -> a

-- | Like Signed, except the codomain can be different to the domain.
class Normed a b
size :: Normed a b => a -> b

-- | distance between numbers
--   
--   <pre>
--   distance a b &gt;= zero
--   distance a a == zero
--   \a b c -&gt; distance a c + distance b c - distance a b &gt;= zero &amp;&amp;
--             distance a b + distance b c - distance a c &gt;= zero &amp;&amp;
--             distance a b + distance a c - distance b c &gt;= zero &amp;&amp;
--   </pre>
class Metric a b
distance :: Metric a b => a -> a -> b

-- | todo: This should probably be split off into some sort of alternative
--   Equality logic, but to what end?
class (AdditiveGroup a) => Epsilon a
nearZero :: Epsilon a => a -> Bool
aboutEqual :: Epsilon a => a -> a -> Bool
positive :: (Epsilon a, Eq a, Signed a) => a -> Bool
veryPositive :: (Epsilon a, Eq a, Signed a) => a -> Bool
veryNegative :: (Epsilon a, Eq a, Signed a) => a -> Bool

-- | todo: is utf perfectly acceptable these days?
(≈) :: (Epsilon a) => a -> a -> Bool
infixl 4 ≈
instance NumHask.Algebra.Metric.Epsilon GHC.Types.Double
instance NumHask.Algebra.Metric.Epsilon GHC.Types.Float
instance NumHask.Algebra.Metric.Epsilon GHC.Types.Int
instance NumHask.Algebra.Metric.Epsilon GHC.Integer.Type.Integer
instance NumHask.Algebra.Metric.Epsilon a => NumHask.Algebra.Metric.Epsilon (Data.Complex.Complex a)
instance NumHask.Algebra.Metric.Metric GHC.Types.Double GHC.Types.Double
instance NumHask.Algebra.Metric.Metric GHC.Types.Float GHC.Types.Float
instance NumHask.Algebra.Metric.Metric GHC.Types.Int GHC.Types.Int
instance NumHask.Algebra.Metric.Metric GHC.Integer.Type.Integer GHC.Integer.Type.Integer
instance (NumHask.Algebra.Multiplicative.Multiplicative a, NumHask.Algebra.Field.ExpField a, NumHask.Algebra.Metric.Normed a a) => NumHask.Algebra.Metric.Metric (Data.Complex.Complex a) a
instance NumHask.Algebra.Metric.Normed GHC.Types.Double GHC.Types.Double
instance NumHask.Algebra.Metric.Normed GHC.Types.Float GHC.Types.Float
instance NumHask.Algebra.Metric.Normed GHC.Types.Int GHC.Types.Int
instance NumHask.Algebra.Metric.Normed GHC.Integer.Type.Integer GHC.Integer.Type.Integer
instance (NumHask.Algebra.Multiplicative.Multiplicative a, NumHask.Algebra.Field.ExpField a, NumHask.Algebra.Metric.Normed a a) => NumHask.Algebra.Metric.Normed (Data.Complex.Complex a) a
instance NumHask.Algebra.Metric.Signed GHC.Types.Double
instance NumHask.Algebra.Metric.Signed GHC.Types.Float
instance NumHask.Algebra.Metric.Signed GHC.Types.Int
instance NumHask.Algebra.Metric.Signed GHC.Integer.Type.Integer


-- | Algebra for Representable numbers
module NumHask.Algebra.Module

-- | Additive Module Laws
--   
--   <pre>
--   (a + b) .+ c == a + (b .+ c)
--   (a + b) .+ c == (a .+ c) + b
--   a .+ zero == a
--   a .+ b == b +. a
--   </pre>
class (Additive a) => AdditiveModule r a
(.+) :: AdditiveModule r a => r a -> a -> r a
(+.) :: AdditiveModule r a => a -> r a -> r a

-- | Subtraction Module Laws
--   
--   <pre>
--   (a + b) .- c == a + (b .- c)
--   (a + b) .- c == (a .- c) + b
--   a .- zero == a
--   a .- b == negate b +. a
--   </pre>
class (AdditiveGroup a, AdditiveModule r a) => AdditiveGroupModule r a
(.-) :: AdditiveGroupModule r a => r a -> a -> r a
(-.) :: AdditiveGroupModule r a => a -> r a -> r a

-- | Multiplicative Module Laws
--   
--   <pre>
--   a .* one == a
--   (a + b) .* c == (a .* c) + (b .* c)
--   c *. (a + b) == (c *. a) + (c *. b)
--   a .* zero == zero
--   a .* b == b *. a
--   </pre>
class (Multiplicative a) => MultiplicativeModule r a
(.*) :: MultiplicativeModule r a => r a -> a -> r a
(*.) :: MultiplicativeModule r a => a -> r a -> r a

-- | Division Module Laws
--   
--   <pre>
--   nearZero a || a ./ one == a
--   b == zero || a ./ b == recip b *. a
--   </pre>
class (MultiplicativeGroup a, MultiplicativeModule r a) => MultiplicativeGroupModule r a
(./) :: MultiplicativeGroupModule r a => r a -> a -> r a
(/.) :: MultiplicativeGroupModule r a => a -> r a -> r a

-- | Banach (with Norm) laws form rules around size and direction of a
--   number, with a potential crossing into another codomain.
--   
--   <pre>
--   a == singleton zero || normalize a *. size a == a
--   </pre>
class (ExpField a, Normed (r a) a, MultiplicativeGroupModule r a) => Banach r a
normalize :: Banach r a => r a -> r a

-- | the inner product of a representable over a semiring
--   
--   <pre>
--   a &lt;.&gt; b == b &lt;.&gt; a
--   a &lt;.&gt; (b +c) == a &lt;.&gt; b + a &lt;.&gt; c
--   a &lt;.&gt; (s *. b + c) == s * (a &lt;.&gt; b) + a &lt;.&gt; c
--   </pre>
--   
--   (s0 *. a) <a>.</a> (s1 *. b) == s0 * s1 * (a <a>.</a> b)
class (Semiring a) => Hilbert r a
(<.>) :: Hilbert r a => r a -> r a -> a

-- | tensorial type

-- | generalised outer product
--   
--   <pre>
--   a&gt;&lt;b + c&gt;&lt;b == (a+c) &gt;&lt; b
--   a&gt;&lt;b + a&gt;&lt;c == a &gt;&lt; (b+c)
--   </pre>
--   
--   todo: work out why these laws down't apply &gt; a *. (b&gt;<a>==
--   (a</a>&lt;b) .* c &gt; (a&gt;<a>.* c == a *. (b</a>&lt;c)
class TensorProduct a
(><) :: TensorProduct a => a -> a -> (a >< a)
outer :: TensorProduct a => a -> a -> (a >< a)
timesleft :: TensorProduct a => a -> (a >< a) -> a
timesright :: TensorProduct a => (a >< a) -> a -> a


-- | Algebraic structure
module NumHask.Algebra


-- | Homomorphic operation from element to structured number
module NumHask.Algebra.Singleton

-- | This class could also be called replicate. Looking forward, however,
--   it may be useful to consider a Representable such as
--   
--   <pre>
--   VectorThing a = Vector a | Single a | Zero
--   </pre>
--   
--   and then
--   
--   <pre>
--   singleton a = Single a
--   singleton zero = Zero
--   </pre>
--   
--   short-circuiting an expensive computation. As the class action then
--   doesn't actually involve replication, it would be mis-named.
class Singleton f
singleton :: Singleton f => a -> f a


-- | A prelude for NumHask
module NumHask.Prelude

module NumHask.Laws
data LawArity a
Nonary :: Bool -> LawArity a
Unary :: (a -> Bool) -> LawArity a
Binary :: (a -> a -> Bool) -> LawArity a
Ternary :: (a -> a -> a -> Bool) -> LawArity a
Ornary :: (a -> a -> a -> a -> Bool) -> LawArity a
Failiary :: (a -> Property) -> LawArity a
data LawArity2 a b
Unary2 :: (a -> Bool) -> LawArity2 a b
Binary2 :: (a -> b -> Bool) -> LawArity2 a b
Ternary2 :: (a -> a -> b -> Bool) -> LawArity2 a b
Ternary2' :: (a -> b -> b -> Bool) -> LawArity2 a b
Ternary2'' :: (a -> a -> a -> Bool) -> LawArity2 a b
Quad31 :: (a -> a -> a -> b -> Bool) -> LawArity2 a b
Quad22 :: (a -> a -> b -> b -> Bool) -> LawArity2 a b
Failiary2 :: (a -> Property) -> LawArity2 a b
type Law a = (TestName, LawArity a)
type Law2 a b = (TestName, LawArity2 a b)
testLawOf :: (Arbitrary a, Show a) => [a] -> Law a -> TestTree
testLawOf2 :: (Arbitrary a, Show a, Arbitrary b, Show b) => [(a, b)] -> Law2 a b -> TestTree
idempotentLaws :: (Eq a, Additive a, Multiplicative a) => [Law a]
additiveLaws :: (Eq a, Additive a) => [Law a]
additiveLawsFail :: (Eq a, Additive a, Show a, Arbitrary a) => [Law a]
additiveGroupLaws :: (Eq a, AdditiveGroup a) => [Law a]
multiplicativeLaws :: (Eq a, Multiplicative a) => [Law a]
multiplicativeLawsFail :: (Eq a, Show a, Arbitrary a, Multiplicative a) => [Law a]
multiplicativeMonoidalLaws :: (Eq a, MultiplicativeUnital a, MultiplicativeAssociative a) => [Law a]
multiplicativeGroupLaws :: (Epsilon a, Eq a, MultiplicativeGroup a) => [Law a]
distributionLaws :: (Eq a, Distribution a) => [Law a]
distributionLawsFail :: (Show a, Arbitrary a, Epsilon a, Eq a, Distribution a) => [Law a]
integralLaws :: (Eq a, Integral a, FromInteger a, ToInteger a) => [Law a]
signedLaws :: (Eq a, Signed a) => [Law a]
metricFloatLaws :: () => [Law Float]
metricComplexFloatLaws :: () => [Law (Complex Float)]
boundedFieldFloatLaws :: [Law Float]
quotientFieldLaws :: (Ord a, Field a, QuotientField a, FromInteger a) => [Law a]
expFieldLaws :: (ExpField a, Signed a, Epsilon a, Fractional a, Ord a) => [Law a]
expFieldComplexLooseLaws :: Float -> [Law (Complex Float)]
additiveBasisLaws :: (Eq (r a), Epsilon (r a), AdditiveBasis r a) => [Law (r a)]
additiveGroupBasisLaws :: (Eq (r a), Singleton r, AdditiveGroupBasis r a) => [Law (r a)]
multiplicativeBasisLaws :: (Eq (r a), Singleton r, MultiplicativeBasis r a) => [Law (r a)]
multiplicativeGroupBasisLaws :: (Eq (r a), Epsilon a, Epsilon (r a), Singleton r, MultiplicativeGroupBasis r a) => [Law (r a)]
additiveModuleLaws :: (Eq (r a), Epsilon a, Epsilon (r a), AdditiveModule r a) => [Law2 (r a) a]
additiveGroupModuleLaws :: (Eq (r a), Epsilon a, Epsilon (r a), AdditiveGroupModule r a) => [Law2 (r a) a]
multiplicativeModuleLaws :: (Eq (r a), Epsilon a, Epsilon (r a), MultiplicativeModule r a) => [Law2 (r a) a]
multiplicativeGroupModuleLawsFail :: (Eq a, Show a, Arbitrary a, Eq (r a), Show (r a), Arbitrary (r a), Epsilon a, Epsilon (r a), MultiplicativeGroupModule r a) => [Law2 (r a) a]
expFieldNaperianLaws :: (ExpField (r a), Foldable r, ExpField a, Epsilon a, Signed a, Epsilon (r a), Fractional a, Ord a) => [Law (r a)]
metricNaperianFloatLaws :: (Metric (r Float) Float) => [Law (r Float)]
tensorProductLaws :: (Eq (r (r a)), Additive (r (r a)), Eq (r a), Eq a, TensorProduct (r a), Epsilon a, Epsilon (r a)) => [Law2 (r a) a]
banachLaws :: (Ord a, Fractional a, Signed a, Foldable r, Fractional b, Eq (r a), Epsilon b, Epsilon (r a), Metric (r a) b, MultiplicativeGroup b, Banach r a, Normed (r a) b, Singleton r) => [Law2 (r a) b]
hilbertLaws :: (Eq (r a), Eq a, Multiplicative a, MultiplicativeModule r a, Epsilon a, Epsilon (r a), Hilbert r a) => [Law2 (r a) a]

-- | semiring
semiringLaws :: (Eq a, Semiring a) => [Law a]

-- | ring
ringLaws :: (Eq a, Ring a) => [Law a]

-- | starsemiring
starSemiringLaws :: (Eq a, StarSemiring a) => [Law a]


-- | NumHask usage examples
module NumHask.Examples
