numhask 0.5.0 → 0.6.0
raw patch · 23 files changed
+782/−588 lines, 23 filesdep +bifunctorsdep +mmorphdep +protoludesetup-changed
Dependencies added: bifunctors, mmorph, protolude, text, transformers
Files
- Setup.hs +0/−2
- numhask.cabal +12/−5
- readme.md +41/−0
- src/NumHask/Algebra/Abstract.hs +13/−15
- src/NumHask/Algebra/Abstract/Action.hs +15/−10
- src/NumHask/Algebra/Abstract/Additive.hs +8/−9
- src/NumHask/Algebra/Abstract/Field.hs +44/−41
- src/NumHask/Algebra/Abstract/Group.hs +24/−19
- src/NumHask/Algebra/Abstract/Lattice.hs +22/−15
- src/NumHask/Algebra/Abstract/Module.hs +4/−3
- src/NumHask/Algebra/Abstract/Multiplicative.hs +9/−9
- src/NumHask/Algebra/Abstract/Ring.hs +55/−22
- src/NumHask/Algebra/Linear/Hadamard.hs +0/−39
- src/NumHask/Analysis/Metric.hs +58/−92
- src/NumHask/Data/Complex.hs +81/−49
- src/NumHask/Data/Integral.hs +55/−39
- src/NumHask/Data/LogField.hs +87/−63
- src/NumHask/Data/Pair.hs +42/−37
- src/NumHask/Data/Positive.hs +33/−29
- src/NumHask/Data/Rational.hs +55/−51
- src/NumHask/Data/Wrapped.hs +34/−34
- src/NumHask/Exception.hs +6/−5
- src/NumHask/Prelude.hs +84/−0
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
numhask.cabal view
@@ -1,6 +1,6 @@-cabal-version: 3.0+cabal-version: 2.4 name: numhask-version: 0.5.0+version: 0.6.0 synopsis: numeric classes description:@@ -25,7 +25,8 @@ Simple extra-doc-files:- other/*.svg+ other/*.svg,+ readme.md source-repository head type:@@ -38,6 +39,7 @@ hs-source-dirs: src default-extensions:+ NoImplicitPrelude NegativeLiterals OverloadedStrings UnicodeSyntax@@ -48,7 +50,12 @@ -Wincomplete-uni-patterns -Wredundant-constraints build-depends:- base >=4.7 && <5+ base >=4.7 && <5,+ protolude >=0.3 && <0.4,+ bifunctors >= 3.2,+ mmorph >= 1.1,+ transformers >= 0.5,+ text >= 1.2 exposed-modules: NumHask.Algebra.Abstract NumHask.Algebra.Abstract.Action@@ -59,7 +66,6 @@ NumHask.Algebra.Abstract.Module NumHask.Algebra.Abstract.Multiplicative NumHask.Algebra.Abstract.Ring- NumHask.Algebra.Linear.Hadamard NumHask.Analysis.Metric NumHask.Data.Complex NumHask.Data.Integral@@ -69,5 +75,6 @@ NumHask.Data.Rational NumHask.Data.Wrapped NumHask.Exception+ NumHask.Prelude other-modules: default-language: Haskell2010
+ readme.md view
@@ -0,0 +1,41 @@+numhask+===++[](https://travis-ci.org/tonyday567/numhask) [](https://gitter.im/numhask/Lobby)++A numeric class hierarchy, providing a structure for numbers and functions that combine them.++Field hierarchy+---++[](numhask/other/field.svg)+++NumHask class structure+---++[](numhask/other/numhask.svg)+++`numhask` begins with separately named magma-derived classes for addition and multiplication, and then being symetrical in the treatment of the two heirarchies. A short magma structure is provided with the intention of supplying appropriate classes for operators that are neither addition nor multiplication, but this structure is not hooked up to the main classes.++To be as compatible as practical with the existing haskell ecosystem. Ints, Integers, Floats, Doubles and Complex are taken from base and given numhask class instances, so they are also Num instances. Monoid and Semigroup are not used in numhask to maintain compatability.++`numhask` replaces all the relevant numeric operators in Prelude, so you're going to get clashes.++QuickCheck tests of numeric laws are included. This also includes tracking where laws are approximate or fail for non-exact numbers.++The usual operators (+) and (*) operators are reserved for commutative relationships, with plus and times being used for non-commutative ones.++In summary, the library doesn't do anything fancy. But if having to define `(*)` when you just want a `(+)` offends your sensibilities, it may bring some sanity.++NumHask.Prelude+---++``` {.sourceCode .literate .haskell}+{-# LANGUAGE NoImplicitPrelude #-}+import NumHask.Prelude+```++'Numhask.Prelude' is designed as a drop-in replacement for Prelude and 'NoImplicitPrelude' is obligatory. Behind the scenes, the module wraps [protolude](https://www.stackage.org/package/protolude).+
src/NumHask/Algebra/Abstract.hs view
@@ -1,30 +1,29 @@ {-# OPTIONS_GHC -Wall #-} -- | The abstract algebraic class structure of a number.--- module NumHask.Algebra.Abstract ( -- * Mapping from Num -- -- $numMap- module NumHask.Algebra.Abstract.Group- , module NumHask.Algebra.Abstract.Additive- , module NumHask.Algebra.Abstract.Multiplicative- , module NumHask.Algebra.Abstract.Ring- , module NumHask.Algebra.Abstract.Field- , module NumHask.Algebra.Abstract.Module- , module NumHask.Algebra.Abstract.Action- , module NumHask.Algebra.Abstract.Lattice+ module NumHask.Algebra.Abstract.Group,+ module NumHask.Algebra.Abstract.Additive,+ module NumHask.Algebra.Abstract.Multiplicative,+ module NumHask.Algebra.Abstract.Ring,+ module NumHask.Algebra.Abstract.Field,+ module NumHask.Algebra.Abstract.Module,+ module NumHask.Algebra.Abstract.Action,+ module NumHask.Algebra.Abstract.Lattice, ) where -import NumHask.Algebra.Abstract.Group+import NumHask.Algebra.Abstract.Action import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Multiplicative-import NumHask.Algebra.Abstract.Ring import NumHask.Algebra.Abstract.Field-import NumHask.Algebra.Abstract.Module-import NumHask.Algebra.Abstract.Action+import NumHask.Algebra.Abstract.Group import NumHask.Algebra.Abstract.Lattice+import NumHask.Algebra.Abstract.Module+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring -- $numMap --@@ -69,4 +68,3 @@ -- > fromInteger :: Integer -> a -- -- `fromInteger` is given its own class `FromInteger`---
src/NumHask/Algebra/Abstract/Action.hs view
@@ -5,12 +5,13 @@ -- | Action module NumHask.Algebra.Abstract.Action- ( Actor- , AdditiveAction(..)- , SubtractiveAction(..)- , MultiplicativeAction(..)- , DivisiveAction(..)- ) where+ ( Actor,+ AdditiveAction (..),+ SubtractiveAction (..),+ MultiplicativeAction (..),+ DivisiveAction (..),+ )+where import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Multiplicative@@ -18,7 +19,8 @@ -- | a type class to represent an action on elements of a higher-kinded number type family Actor h -class (Additive (Actor h)) =>+class+ (Additive (Actor h)) => AdditiveAction h where infixl 6 .+ (.+) :: h -> Actor h -> h@@ -26,7 +28,8 @@ infixl 6 +. (+.) :: Actor h -> h -> h -class (Subtractive (Actor h)) =>+class+ (Subtractive (Actor h)) => SubtractiveAction h where infixl 6 .- (.-) :: h -> Actor h -> h@@ -34,14 +37,16 @@ infixl 6 -. (-.) :: Actor h -> h -> h -class (Multiplicative (Actor h)) =>+class+ (Multiplicative (Actor h)) => MultiplicativeAction h where infixl 7 .* (.*) :: h -> Actor h -> h infixl 7 *. (*.) :: Actor h -> h -> h -class (Divisive (Actor h)) =>+class+ (Divisive (Actor h)) => DivisiveAction h where infixl 7 ./ (./) :: h -> Actor h -> h
src/NumHask/Algebra/Abstract/Additive.hs view
@@ -2,16 +2,16 @@ -- | Additive module NumHask.Algebra.Abstract.Additive- ( Additive(..)- , sum- , Subtractive(..)+ ( Additive (..),+ sum,+ Subtractive (..), ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import Prelude (Int, Integer, Float, Double, Bool)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Bool, Double, Float, Int, Integer) import qualified Prelude as P -- | For practical reasons, 'Additive' has no super classes. Using `Associative` and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.@@ -149,9 +149,8 @@ instance Subtractive Word64 where negate = P.negate - instance Additive b => Additive (a -> b) where- f + f' = \a -> f a + f' a + f + f' = \a -> f a + f' a zero _ = zero instance Subtractive b => Subtractive (a -> b) where
src/NumHask/Algebra/Abstract/Field.hs view
@@ -1,21 +1,20 @@ {-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wall #-} -- | Field classes module NumHask.Algebra.Abstract.Field- ( Field- , ExpField(..)- , QuotientField(..)- , UpperBoundedField(..)- , LowerBoundedField(..)- , TrigField(..)- , half+ ( Field,+ ExpField (..),+ QuotientField (..),+ UpperBoundedField (..),+ LowerBoundedField (..),+ TrigField (..),+ half, ) where @@ -24,8 +23,8 @@ import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring import NumHask.Data.Integral-import qualified Prelude as P import Prelude ((.))+import qualified Prelude as P -- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set -- on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.@@ -52,8 +51,9 @@ -- > recip a = one / a -- > recip a * a = one -- > a * recip a = one-class (Distributive a, Subtractive a, Divisive a) =>- Field a+class+ (Distributive a, Subtractive a, Divisive a) =>+ Field a instance Field P.Double @@ -66,8 +66,9 @@ -- > sqrt . (**2) == identity -- > log . exp == identity -- > for +ive b, a != 0,1: a ** logBase a b ≈ b-class (Field a) =>- ExpField a where+class+ (Field a) =>+ ExpField a where exp :: a -> a log :: a -> a logBase :: a -> a -> a@@ -101,29 +102,30 @@ properFraction :: a -> (b, a) round :: a -> b- default round ::(P.Ord a, P.Ord b, Subtractive b, Integral b) => a -> b+ default round :: (P.Ord a, P.Ord b, Subtractive b, Integral b) => a -> b round x = case properFraction x of- (n,r) -> let- m = bool (n+one) (n-one) (r P.< zero)- half_down = abs' r - (one/(one+one))- abs' a- | a P.< zero = negate a- | P.otherwise = a- in- case P.compare half_down zero of- P.LT -> n- P.EQ -> bool m n (even n)- P.GT -> m+ (n, r) ->+ let m = bool (n + one) (n - one) (r P.< zero)+ half_down = abs' r - (one / (one + one))+ abs' a+ | a P.< zero = negate a+ | P.otherwise = a+ in case P.compare half_down zero of+ P.LT -> n+ P.EQ -> bool m n (even n)+ P.GT -> m ceiling :: a -> b default ceiling :: (P.Ord a) => a -> b- ceiling x = bool n (n+one) (r P.>= zero)- where (n,r) = properFraction x+ ceiling x = bool n (n + one) (r P.>= zero)+ where+ (n, r) = properFraction x floor :: a -> b default floor :: (P.Ord a, Subtractive b) => a -> b- floor x = bool n (n-one) (r P.< zero)- where (n,r) = properFraction x+ floor x = bool n (n - one) (r P.< zero)+ where+ (n, r) = properFraction x truncate :: a -> b default truncate :: (P.Ord a) => a -> b@@ -137,7 +139,7 @@ instance QuotientField b c => QuotientField (a -> b) (a -> c) where properFraction f = (P.fst . frac, P.snd . frac)- where+ where frac a = properFraction @b @c (f a) round f = round . f@@ -155,9 +157,9 @@ -- > zero / zero != nan -- -- 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) =>- UpperBoundedField a where-+class+ (Field a) =>+ UpperBoundedField a where infinity :: a infinity = one / zero @@ -172,9 +174,9 @@ infinity _ = infinity nan _ = nan -class (Subtractive a, Field a) =>- LowerBoundedField a where-+class+ (Subtractive a, Field a) =>+ LowerBoundedField a where negInfinity :: a negInfinity = negate (one / zero) @@ -186,8 +188,9 @@ negInfinity _ = negInfinity -- | Trigonometric Field-class (Field a) =>- TrigField a where+class+ (Field a) =>+ TrigField a where pi :: a sin :: a -> a cos :: a -> a
src/NumHask/Algebra/Abstract/Group.hs view
@@ -4,21 +4,22 @@ -- | The Group hierarchy module NumHask.Algebra.Abstract.Group- ( Magma(..)- , Unital(..)- , Associative- , Commutative- , Absorbing(..)- , Invertible(..)- , Idempotent- , Group- , AbelianGroup+ ( Magma (..),+ Unital (..),+ Associative,+ Commutative,+ Absorbing (..),+ Invertible (..),+ Idempotent,+ Group,+ AbelianGroup, ) where import Prelude -- * Magma structure+ -- | A <https://en.wikipedia.org/wiki/Magma_(algebra) Magma> is a tuple (T,magma) consisting of -- -- - a type a, and@@ -36,8 +37,6 @@ -- > ∀ a, b ∈ T: a magma b ∈ T -- -- These laws are true by construction in haskell: the type signature of 'magma' and the above mathematical laws are synonyms.------ class Magma a where magma :: a -> a -> a @@ -51,8 +50,8 @@ -- -- > unit magma a = a -- > a magma unit = a----class Magma a =>+class+ Magma a => Unital a where unit :: a @@ -63,7 +62,8 @@ -- | An Associative Magma -- -- > (a magma b) magma c = a magma (b magma c)-class Magma a =>+class+ Magma a => Associative a instance Associative b => Associative (a -> b)@@ -72,7 +72,8 @@ -- <https://en.wikipedia.org/wiki/Commutative_property commutative>. -- -- > a magma b = b magma a-class Magma a =>+class+ Magma a => Commutative a instance Commutative b => Commutative (a -> b)@@ -80,8 +81,8 @@ -- | An Invertible Magma -- -- > ∀ a,b ∈ T: inv a `magma` (a `magma` b) = b = (b `magma` a) `magma` inv a----class Magma a =>+class+ Magma a => Invertible a where inv :: a -> a @@ -92,13 +93,15 @@ -- | A <https://en.wikipedia.org/wiki/Group_(mathematics) Group> is a -- Associative, Unital and Invertible Magma. class (Associative a, Unital a, Invertible a) => Group a+ instance (Associative a, Unital a, Invertible a) => Group a -- | An Absorbing is a Magma with an -- <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element> -- -- > a `times` absorb = absorb-class Magma a =>+class+ Magma a => Absorbing a where absorb :: a @@ -110,7 +113,8 @@ -- <https://en.wikipedia.org/wiki/Idempotence Idempotent>. -- -- > a magma a = a-class Magma a =>+class+ Magma a => Idempotent a instance Idempotent b => Idempotent (a -> b)@@ -119,4 +123,5 @@ -- Associative, Unital, Invertible and Commutative Magma . In other words, it -- is a Commutative Group class (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a+ instance (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a
src/NumHask/Algebra/Abstract/Lattice.hs view
@@ -4,10 +4,19 @@ module NumHask.Algebra.Abstract.Lattice where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..)) import NumHask.Algebra.Abstract.Field+import Data.Bool+import Data.Eq+import GHC.Float (Float, Double)+import GHC.Int (Int)+import GHC.Num (Integer)+import GHC.Word (Word)+import Data.Ord (Ord(..))+import GHC.Enum (Bounded(..))+import Data.Function (const) -- | A algebraic structure with element joins: <http://en.wikipedia.org/wiki/Semilattice> --@@ -15,8 +24,8 @@ -- > Commutativity: x \/ y == y \/ x -- > Idempotency: x \/ x == x class (Eq a) => JoinSemiLattice a where- infixr 5 \/- (\/) :: a -> a -> a+ infixr 5 \/+ (\/) :: a -> a -> a -- | The partial ordering induced by the join-semilattice structure joinLeq :: (JoinSemiLattice a) => a -> a -> Bool@@ -28,8 +37,8 @@ -- > Commutativity: x /\ y == y /\ x -- > Idempotency: x /\ x == x class (Eq a) => MeetSemiLattice a where- infixr 6 /\- (/\) :: a -> a -> a+ infixr 6 /\+ (/\) :: a -> a -> a -- | The partial ordering induced by the meet-semilattice structure meetLeq :: (MeetSemiLattice a) => a -> a -> Bool@@ -40,22 +49,24 @@ -- -- > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a class (JoinSemiLattice a, MeetSemiLattice a) => Lattice a+ instance (JoinSemiLattice a, MeetSemiLattice a) => Lattice a -- | A join-semilattice with an identity element 'bottom' for '\/'. -- -- > Identity: x \/ bottom == x class JoinSemiLattice a => BoundedJoinSemiLattice a where- bottom :: a+ bottom :: a -- | A meet-semilattice with an identity element 'top' for '/\'. -- -- > Identity: x /\ top == x class MeetSemiLattice a => BoundedMeetSemiLattice a where- top :: a+ top :: a -- | Lattices with both bounds class (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a+ instance (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a instance JoinSemiLattice Float where@@ -149,10 +160,10 @@ (/\) = max instance (Eq (a -> b), JoinSemiLattice b) => JoinSemiLattice (a -> b) where- f \/ f' = \a -> f a \/ f' a + f \/ f' = \a -> f a \/ f' a instance (Eq (a -> b), MeetSemiLattice b) => MeetSemiLattice (a -> b) where- f /\ f' = \a -> f a /\ f' a + f /\ f' = \a -> f a /\ f' a -- from here @@ -242,7 +253,3 @@ instance (Eq (a -> b), BoundedMeetSemiLattice b) => BoundedMeetSemiLattice (a -> b) where top = const top----
src/NumHask/Algebra/Abstract/Module.hs view
@@ -4,11 +4,12 @@ -- | Algebra for Modules module NumHask.Algebra.Abstract.Module- ( Module- ) where+ ( Module,+ )+where -import NumHask.Algebra.Abstract.Ring import NumHask.Algebra.Abstract.Action+import NumHask.Algebra.Abstract.Ring -- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module> over r a is -- a (Ring a), an abelian (Group r a) and a scalar multiplier (.*, *.) with the
src/NumHask/Algebra/Abstract/Multiplicative.hs view
@@ -2,16 +2,16 @@ -- | Multiplicative module NumHask.Algebra.Abstract.Multiplicative- ( Multiplicative(..)- , product- , Divisive(..)+ ( Multiplicative (..),+ product,+ Divisive (..), ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import Prelude (Int, Integer, Float, Double)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Double, Float, Int, Integer) import qualified Prelude as P -- | For practical reasons, 'Multiplicative' has no super classes. Using 'Associative' and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.@@ -23,7 +23,6 @@ -- -- By convention, (*) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative multiplication seems a bit dogmatic. class Multiplicative a where- infixl 7 * (*) :: a -> a -> a @@ -83,6 +82,7 @@ instance Multiplicative Int16 where (*) = (P.*) one = 1+ instance Multiplicative Int32 where (*) = (P.*) one = 1@@ -112,7 +112,7 @@ one = 1 instance Multiplicative b => Multiplicative (a -> b) where- f * f' = \a -> f a * f' a + f * f' = \a -> f a * f' a one _ = one instance Divisive b => Divisive (a -> b) where
src/NumHask/Algebra/Abstract/Ring.hs view
@@ -4,20 +4,20 @@ -- | Ring module NumHask.Algebra.Abstract.Ring- ( Distributive- , Semiring- , Ring- , IntegralDomain- , StarSemiring(..)- , KleeneAlgebra- , InvolutiveRing(..)- , two+ ( Distributive,+ Semiring,+ Ring,+ IntegralDomain,+ StarSemiring (..),+ KleeneAlgebra,+ InvolutiveRing (..),+ two, ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..)) import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Group import NumHask.Algebra.Abstract.Multiplicative@@ -31,46 +31,68 @@ -- > a * zero == zero -- -- The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element annihilation> laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.-class (Additive a, Multiplicative a) =>+class+ (Additive a, Multiplicative a) => Distributive a instance Distributive P.Double+ instance Distributive P.Float+ instance Distributive P.Int+ instance Distributive P.Integer+ instance Distributive Natural+ instance Distributive Int8+ instance Distributive Int16+ instance Distributive Int32+ instance Distributive Int64+ instance Distributive Word+ instance Distributive Word8+ instance Distributive Word16+ instance Distributive Word32+ instance Distributive Word64+ instance Distributive P.Bool+ instance Distributive b => Distributive (a -> b) -- | A <https://en.wikipedia.org/wiki/Semiring Semiring> is commutative monoidal under addition, has a monoidal multiplication operator (not necessarily commutative), and where multiplication distributes over addition.-class (Distributive a) =>- Semiring a where-instance (Distributive a) =>+class+ (Distributive a) => Semiring a +instance+ (Distributive a) =>+ Semiring a+ -- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian -- group under addition and monoidal under multiplication, and where multiplication -- distributes over addition.-class (Distributive a, Subtractive a) =>+class+ (Distributive a, Subtractive a) => Ring a-instance (Distributive a, Subtractive a) =>++instance+ (Distributive a, Subtractive a) => Ring a -- | An <https://en.wikipedia.org/wiki/Integral_domain Integral Domain> -- generalizes a ring of integers by requiring the product of any two nonzero -- elements to be nonzero. This means that if a ≠ 0, an equality ab = ac -- implies b = c.----class (Distributive a) =>+class+ (Distributive a) => IntegralDomain a instance IntegralDomain P.Double@@ -83,7 +105,6 @@ -- is a semiring with an additional unary operator star satisfying: -- -- > star a = one + a `times` star a--- class (Distributive a) => StarSemiring a where star :: a -> a star a = one + plus a@@ -98,7 +119,6 @@ -- -- > a `times` x + x = a ==> star a `times` x + x = x -- > x `times` a + x = a ==> x `times` star a + x = x--- class (StarSemiring a, Idempotent a) => KleeneAlgebra a instance KleeneAlgebra b => KleeneAlgebra (a -> b)@@ -111,25 +131,38 @@ -- > adj (adj a) ==> a -- -- Note: elements for which @adj a == a@ are called "self-adjoint".--- class (Distributive a) => InvolutiveRing a where adj :: a -> a adj x = x instance InvolutiveRing P.Double+ instance InvolutiveRing P.Float+ instance InvolutiveRing P.Integer+ instance InvolutiveRing P.Int+ instance InvolutiveRing Natural+ instance InvolutiveRing Int8+ instance InvolutiveRing Int16+ instance InvolutiveRing Int32+ instance InvolutiveRing Int64+ instance InvolutiveRing Word+ instance InvolutiveRing Word8+ instance InvolutiveRing Word16+ instance InvolutiveRing Word32+ instance InvolutiveRing Word64+ instance InvolutiveRing b => InvolutiveRing (a -> b) -- | Defining 'two' requires adding the multiplicative unital to itself.
− src/NumHask/Algebra/Linear/Hadamard.hs
@@ -1,39 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# OPTIONS_GHC -Wall #-}---- | Element-by-element operations-module NumHask.Algebra.Linear.Hadamard- ( HadamardMultiplication(..)- , HadamardDivision(..)- , Hadamard- )-where--import NumHask.Algebra.Abstract.Multiplicative---- | element by element multiplication------ > (a .*. b) .*. c == a .*. (b .*. c)--- > singleton one .*. a = a--- > a .*. singleton one = a--- > a .*. b == b .*. a-class (Multiplicative a) =>- HadamardMultiplication m a where- infixl 7 .*.- (.*.) :: m a -> m a -> m a----- | element by element division------ > a ./. a == singleton one-class (Divisive a) =>- HadamardDivision m a where- infixl 7 ./.- (./.) :: m a -> m a -> m a--class (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a-instance (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a-
src/NumHask/Analysis/Metric.hs view
@@ -4,35 +4,35 @@ -- | Metric classes module NumHask.Analysis.Metric- ( Signed(..)- , Normed(..)- , Metric(..)- , Epsilon(..)- , (~=)+ ( Signed (..),+ Normed (..),+ Metric (..),+ Epsilon (..),+ (~=), ) where -import qualified Prelude as P-import Prelude- hiding ( Bounded(..)- , Integral(..)- , (-)- , negate- )--import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..)) import NumHask.Algebra.Abstract.Additive-import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Lattice+import NumHask.Algebra.Abstract.Multiplicative+import Prelude hiding+ ( (-),+ Bounded (..),+ Integral (..),+ negate,+ )+import qualified Prelude as P -- | 'signum' from base is not an operator replicated in numhask, being such a very silly name, and preferred is the much more obvious 'sign'. Compare with 'Norm' where there is a change in codomain -- -- > abs a * sign a == a -- -- 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 (Multiplicative a) =>+class+ (Multiplicative a) => Signed a where sign :: a -> a abs :: a -> a@@ -129,146 +129,112 @@ | otherwise = one abs = P.abs --- | L1 and L2 norms are provided for potential speedups, as well as the generalized p-norm.------ for p >= 1+-- | Cab be Normed ----- > normLp p a >= zero--- > normLp p zero == zero+-- > norm a >= zero+-- > norm zero == zero -- -- Note that the Normed codomain can be different to the domain.--- class (Additive a, Additive b) => Normed a b where- normL1 :: a -> b- normL2 :: a -> b+ norm :: a -> b instance Normed Double Double where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Float Float where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Int Int where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Integer Integer where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Natural Natural where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Int8 Int8 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Int16 Int16 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Int32 Int32 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Int64 Int64 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Word Word where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Word8 Word8 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Word16 Word16 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Word32 Word32 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs instance Normed Word64 Word64 where- normL1 = P.abs- normL2 = P.abs+ norm = P.abs --- | distance between numbers using L1, L2 or Lp-norms+-- | distance between numbers using L1 norm ----- > distanceL2 a b >= zero--- > distanceL2 a a == zero--- > \a b c -> distanceL2 a c + distanceL2 b c - distanceL2 a b >= zero &&--- > distanceL2 a b + distanceL2 b c - distanceL2 a c >= zero &&--- > distanceL2 a b + distanceL2 a c - distanceL2 b c >= zero &&+-- > distance a b >= zero+-- > distance a a == zero+-- class Metric a b where- distanceL1 :: a -> a -> b- distanceL2 :: a -> a -> b+ distance :: a -> a -> b instance Metric Double Double where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Float Float where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Int Int where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Integer Integer where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Natural Natural where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) instance Metric Int8 Int8 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Int16 Int16 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Int32 Int32 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance Metric Int64 Int64 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) + -- fixme: circular distance may be more appropriate instance Metric Word Word where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) instance Metric Word8 Word8 where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) instance Metric Word16 Word16 where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) instance Metric Word32 Word32 where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) instance Metric Word64 Word64 where- distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)- distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)+ distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b) -class (Eq a, Additive a, Subtractive a, MeetSemiLattice a) =>+class+ (Eq a, Additive a, Subtractive a, MeetSemiLattice a) => Epsilon a where- epsilon :: a epsilon = zero
src/NumHask/Data/Complex.hs view
@@ -8,7 +8,17 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wall #-} -module NumHask.Data.Complex where+module NumHask.Data.Complex+ ( Complex (..),+ realPart,+ imagPart,+ mkPolar,+ cis,+ polar,+ magnitude,+ phase,+ )+where import Data.Data (Data) import GHC.Generics (Generic, Generic1)@@ -19,9 +29,20 @@ import NumHask.Algebra.Abstract.Ring import NumHask.Analysis.Metric import NumHask.Data.Integral-import Prelude- hiding (Num(..), (/), atan, cos, exp, log, negate, pi, recip, sin, sqrt)-import qualified Prelude as P (Ord(..), (&&), (<), (<=), (==), (>), otherwise)+import Prelude hiding+ ( (/),+ Num (..),+ atan,+ cos,+ exp,+ log,+ negate,+ pi,+ recip,+ sin,+ sqrt,+ )+import qualified Prelude as P ((&&), (<), (<=), (==), (>), Ord (..), otherwise) -- ----------------------------------------------------------------------------- -- The Complex type@@ -34,19 +55,21 @@ -- has the phase of @z@, but unit magnitude. -- -- The 'Foldable' and 'Traversable' instances traverse the real part first.-data Complex a =- !a :+ !a -- ^ forms a complex number from its real and imaginary- -- rectangular components.- deriving ( Eq- , Show- , Read- , Data- , Generic- , Generic1- , Functor- , Foldable- , Traversable- )+data Complex a+ = -- | forms a complex number from its real and imaginary+ -- rectangular components.+ !a :+ !a+ deriving+ ( Eq,+ Show,+ Read,+ Data,+ Generic,+ Generic1,+ Functor,+ Foldable,+ Traversable+ ) -- | Extracts the real part of a complex number. realPart :: Complex a -> a@@ -63,37 +86,48 @@ instance (Subtractive a) => Subtractive (Complex a) where negate (rx :+ ix) = negate rx :+ negate ix -instance (Distributive a, Subtractive a) =>+instance+ (Distributive a, Subtractive a) => Distributive (Complex a) -instance (Subtractive a, Multiplicative a) =>- Multiplicative (Complex a) where+instance+ (Subtractive a, Multiplicative a) =>+ Multiplicative (Complex a)+ where (rx :+ ix) * (ry :+ iy) = (rx * ry - ix * iy) :+ (ix * ry + iy * rx) one = one :+ zero -instance (Subtractive a, Divisive a) =>- Divisive (Complex a) where+instance+ (Subtractive a, Divisive a) =>+ Divisive (Complex a)+ where recip (rx :+ ix) = (rx * d) :+ (negate ix * d) where d = recip ((rx * rx) + (ix * ix)) -instance (Additive a, FromIntegral a b) =>- FromIntegral (Complex a) b where+instance+ (Additive a, FromIntegral a b) =>+ FromIntegral (Complex a) b+ where fromIntegral_ x = fromIntegral_ x :+ zero -instance (Multiplicative a, ExpField a, Normed a a) =>- Normed (Complex a) a where- normL1 (rx :+ ix) = normL1 rx + normL1 ix- normL2 (rx :+ ix) = sqrt (rx * rx + ix * ix)+instance+ (ExpField a, Normed a a) =>+ Normed (Complex a) a+ where+ norm (rx :+ ix) = norm rx + norm ix -instance (Multiplicative a, Subtractive a, ExpField a, Normed a a) =>- Metric (Complex a) a where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+instance+ (Subtractive a, ExpField a, Normed a a) =>+ Metric (Complex a) a+ where+ distance a b = norm (a - b) -instance (Ord a, Signed a, Subtractive a, Epsilon a)- => Epsilon (Complex a) where+instance+ (Ord a, Signed a, Subtractive a, Epsilon a) =>+ Epsilon (Complex a)+ where epsilon = epsilon :+ epsilon nearZero (a :+ b) = nearZero a && nearZero b @@ -135,13 +169,13 @@ top = top :+ top -- * Helpers from Data.Complex+ mkPolar :: TrigField a => a -> a -> Complex a mkPolar r theta = (r * cos theta) :+ (r * sin theta) -- | @'cis' t@ is a complex value with magnitude @1@ -- and phase @t@ (modulo @2*'pi'@).-{-# SPECIALISE cis :: Double -> Complex Double #-}-+{-# SPECIALIZE cis :: Double -> Complex Double #-} cis :: TrigField a => a -> Complex a cis theta = cos theta :+ sin theta @@ -149,27 +183,25 @@ -- returns a (magnitude, phase) pair in canonical form: -- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@; -- if the magnitude is zero, then so is the phase.-{-# SPECIALISE polar :: Complex Double -> (Double, Double) #-}-+{-# SPECIALIZE polar :: Complex Double -> (Double, Double) #-} polar :: (RealFloat a, ExpField a) => Complex a -> (a, a) polar z = (magnitude z, phase z) -- | The nonnegative magnitude of a complex number.-{-# SPECIALISE magnitude :: Complex Double -> Double #-}-+{-# SPECIALIZE magnitude :: Complex Double -> Double #-} magnitude :: (ExpField a, RealFloat a) => Complex a -> a-magnitude (x :+ y) = scaleFloat- k- (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y)))- where- k = max (exponent x) (exponent y)- mk = -k- sqr z = z * z+magnitude (x :+ y) =+ scaleFloat+ k+ (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y)))+ where+ k = max (exponent x) (exponent y)+ mk = - k+ sqr z = z * z -- | The phase of a complex number, in the range @(-'pi', 'pi']@. -- If the magnitude is zero, then so is the phase.-{-# SPECIALISE phase :: Complex Double -> Double #-}-+{-# SPECIALIZE phase :: Complex Double -> Double #-} phase :: (RealFloat a) => Complex a -> a phase (0 :+ 0) = 0 -- SLPJ July 97 from John Peterson phase (x :+ y) = atan2 y x
src/NumHask/Data/Integral.hs view
@@ -1,41 +1,42 @@-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wall #-} -- | Integral classes module NumHask.Data.Integral- ( Integral(..)- , ToIntegral(..)- , ToInteger- , toInteger- , FromIntegral(..)- , FromInteger(..)- , fromIntegral- , even- , odd- , (^)- , (^^)+ ( Integral (..),+ ToIntegral (..),+ ToInteger,+ toInteger,+ FromIntegral (..),+ FromInteger (..),+ fromIntegral,+ even,+ odd,+ (^),+ (^^), ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..)) import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring-import Prelude (Double, Float, Int, Integer, (.), fst, snd)+import Prelude ((.), Double, Float, Int, Integer, fst, snd) import qualified Prelude as P -- | Integral laws -- -- > b == zero || b * (a `div` b) + (a `mod` b) == a-class (Distributive a) =>+class+ (Distributive a) => Integral a where infixl 7 `div`, `mod` div :: a -> a -> a@@ -288,18 +289,31 @@ fromInteger = fromIntegral_ instance FromInteger Integer+ instance FromInteger Int+ instance FromInteger Double+ instance FromInteger Float+ instance FromInteger Natural+ instance FromInteger Int8+ instance FromInteger Int16+ instance FromInteger Int32+ instance FromInteger Int64+ instance FromInteger Word+ instance FromInteger Word8+ instance FromInteger Word16+ instance FromInteger Word32+ instance FromInteger Word64 -- $operators@@ -311,32 +325,34 @@ odd = P.not . even -------------------------------------------------------+ -- | raise a number to a non-negative integral power-(^)- :: (P.Ord b, Multiplicative a, Integral b)- => a- -> b- -> a+(^) ::+ (P.Ord b, Multiplicative a, Integral b) =>+ a ->+ b ->+ a x0 ^ y0 | y0 P.< zero = P.undefined | -- P.errorWithoutStackTrace "Negative exponent"- y0 P.== zero = one+ y0 P.== zero =+ one | P.otherwise = f x0 y0 where+ -- f : x0 ^ y0 = x ^ y+ f x y+ | even y = f (x * x) (y `quot` two)+ | y P.== one = x+ | P.otherwise = g (x * x) (y `quot` two) x+ -- See Note [Half of y - 1]+ -- g : x0 ^ y0 = (x ^ y) * z+ g x y z+ | even y = g (x * x) (y `quot` two) z+ | y P.== one = x * z+ | P.otherwise = g (x * x) (y `quot` two) (x * z) - -- f : x0 ^ y0 = x ^ y- f x y- | even y = f (x * x) (y `quot` two)- | y P.== one = x- | P.otherwise = g (x * x) (y `quot` two) x- -- See Note [Half of y - 1]- -- g : x0 ^ y0 = (x ^ y) * z- g x y z- | even y = g (x * x) (y `quot` two) z- | y P.== one = x * z- | P.otherwise = g (x * x) (y `quot` two) (x * z)- -- See Note [Half of y - 1]+-- See Note [Half of y - 1] -(^^)- :: (Divisive a, Subtractive b, Integral b, P.Ord b) => a -> b -> a+(^^) ::+ (Divisive a, Subtractive b, Integral b, P.Ord b) => a -> b -> a (^^) x n = if n P.>= zero then x ^ n else recip (x ^ negate n)
src/NumHask/Data/LogField.hs view
@@ -10,35 +10,38 @@ module NumHask.Data.LogField ( -- * @LogField@- LogField()- , logField- , fromLogField+ LogField (),+ logField,+ fromLogField,+ -- ** Isomorphism to log-domain- , logToLogField- , logFromLogField+ logToLogField,+ logFromLogField,+ -- ** Additional operations- , accurateSum- , accurateProduct- , pow+ accurateSum,+ accurateProduct,+ pow, ) where import Data.Data (Data)+import qualified Data.Foldable as F import GHC.Generics (Generic, Generic1) import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Lattice import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring-import NumHask.Algebra.Abstract.Lattice import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Data.Rational-import Prelude hiding (Num(..), exp, log, negate)-import qualified Data.Foldable as F+import Prelude hiding (Num (..), exp, log, negate) -- LogField is adapted from LogFloat ---------------------------------------------------------------- -- ~ 2015.08.06+ -- | -- Module : Data.Number.LogFloat -- Copyright : Copyright (c) 2007--2015 wren gayle romano@@ -50,6 +53,7 @@ ---------------------------------------------------------------- ---------------------------------------------------------------- --+ -- | A @LogField@ is just a 'Field' with a special interpretation. -- The 'LogField' function is presented instead of the constructor, -- in order to ensure semantic conversion. At present the 'Show'@@ -89,18 +93,19 @@ -- -- [1] That is, true up-to underflow and floating point fuzziness. -- Which is, of course, the whole point of this module.-newtype LogField a =- LogField a- deriving ( Eq- , Ord- , Read- , Data- , Generic- , Generic1- , Functor- , Foldable- , Traversable- )+newtype LogField a+ = LogField a+ deriving+ ( Eq,+ Ord,+ Read,+ Data,+ Generic,+ Generic1,+ Functor,+ Foldable,+ Traversable+ ) ---------------------------------------------------------------- -- To show it, we want to show the normal-domain value rather than@@ -114,9 +119,10 @@ instance (ExpField a, Show a) => Show (LogField a) where showsPrec p (LogField x) = let y = exp x- in y `seq` showParen (p > 9) (showString "LogField " . showsPrec 11 y)+ in y `seq` showParen (p > 9) (showString "LogField " . showsPrec 11 y) ----------------------------------------------------------------+ -- | Constructor which does semantic conversion from normal-domain -- to log-domain. Throws errors on negative and NaN inputs. If @p@ -- is non-negative, then following equivalence holds:@@ -136,7 +142,6 @@ -- equivalence holds (without qualification): -- -- > fromLogField == exp . logFromLogField--- fromLogField :: ExpField a => LogField a -> a {-# INLINE [0] fromLogField #-} fromLogField (LogField x) = exp x@@ -151,10 +156,11 @@ -- fire, we have to delay the inlining on two of the four -- con-\/destructors. {-# RULES-"log/fromLogField" forall x . log (fromLogField x) =- logFromLogField x-"fromLogField/LogField" forall x . fromLogField (LogField x) = x- #-}+"log/fromLogField" forall x.+ log (fromLogField x) =+ logFromLogField x+"fromLogField/LogField" forall x. fromLogField (LogField x) = x+ #-} log1p :: ExpField a => a -> a {-# INLINE [0] log1p #-}@@ -165,12 +171,14 @@ expm1 x = exp x - one {-# RULES-"expm1/log1p" forall x . expm1 (log1p x) = x-"log1p/expm1" forall x . log1p (expm1 x) = x- #-}+"expm1/log1p" forall x. expm1 (log1p x) = x+"log1p/expm1" forall x. log1p (expm1 x) = x+ #-} -instance (ExpField a, LowerBoundedField a, Ord a) =>- Additive (LogField a) where+instance+ (ExpField a, LowerBoundedField a, Ord a) =>+ Additive (LogField a)+ where x@(LogField x') + y@(LogField y') | x == zero && y == zero = zero | x == zero = y@@ -180,31 +188,38 @@ zero = LogField negInfinity -instance (ExpField a, Ord a, LowerBoundedField a, UpperBoundedField a) =>- Subtractive (LogField a) where+instance+ (ExpField a, Ord a, LowerBoundedField a, UpperBoundedField a) =>+ Subtractive (LogField a)+ where negate x | x == zero = zero | otherwise = nan -instance (LowerBoundedField a, Eq a) =>- Multiplicative (LogField a) where+instance+ (LowerBoundedField a, Eq a) =>+ Multiplicative (LogField a)+ where (LogField x) * (LogField y) | x == negInfinity || y == negInfinity = LogField negInfinity | otherwise = LogField (x + y) one = LogField zero -instance (LowerBoundedField a, Eq a) =>- Divisive (LogField a) where+instance+ (LowerBoundedField a, Eq a) =>+ Divisive (LogField a)+ where recip (LogField x) = LogField $ negate x -instance (Ord a, LowerBoundedField a, ExpField a) =>+instance+ (Ord a, LowerBoundedField a, ExpField a) => Distributive (LogField a) instance (Field (LogField a), ExpField a, LowerBoundedField a, Ord a) => ExpField (LogField a) where- exp (LogField x) = LogField $ exp x- log (LogField x) = LogField $ log x- (**) x (LogField y) = pow x $ exp y+ exp (LogField x) = LogField $ exp x+ log (LogField x) = LogField $ log x+ (**) x (LogField y) = pow x $ exp y instance (FromIntegral a b, ExpField a) => FromIntegral (LogField a) b where fromIntegral_ = logField . fromIntegral_@@ -224,31 +239,39 @@ instance (Ord a) => MeetSemiLattice (LogField a) where (/\) = max -instance (Epsilon a, ExpField a, LowerBoundedField a, UpperBoundedField a, Ord a) =>- Epsilon (LogField a) where+instance+ (Epsilon a, ExpField a, LowerBoundedField a, UpperBoundedField a, Ord a) =>+ Epsilon (LogField a)+ where epsilon = logField epsilon nearZero (LogField x) = nearZero $ exp x aboutEqual (LogField x) (LogField y) = aboutEqual (exp x) (exp y) instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) => Field (LogField a) -instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>+instance+ (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) => LowerBoundedField (LogField a) -instance (Ord a, ExpField a, LowerBoundedField a) =>- IntegralDomain (LogField a) where+instance+ (Ord a, ExpField a, LowerBoundedField a) =>+ IntegralDomain (LogField a) -instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>+instance+ (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) => UpperBoundedField (LogField a) -instance (Ord a, LowerBoundedField a, UpperBoundedField a, ExpField a) =>- Signed (LogField a) where+instance+ (Ord a, LowerBoundedField a, UpperBoundedField a, ExpField a) =>+ Signed (LogField a)+ where sign a | a == negInfinity = zero | otherwise = one abs = id ----------------------------------------------------------------+ -- | /O(1)/. Compute powers in the log-domain; that is, the following -- equivalence holds (modulo underflow and all that): --@@ -257,6 +280,7 @@ -- /Since: 0.13/ pow :: (ExpField a, LowerBoundedField a, Ord a) => LogField a -> a -> LogField a {-# INLINE pow #-}+ infixr 8 `pow` pow x@(LogField x') m@@ -271,6 +295,7 @@ -- logsumexp[1000,1001,1000] ~~ 1001.55 == 1000 + 1.55 -- logsumexp[-1000,-999,-1000] ~~ -998.45 == -1000 + 1.55 --+ -- | /O(n)/. Compute the sum of a finite list of 'LogField's, being -- careful to avoid underflow issues. That is, the following -- equivalence holds (modulo underflow and all that):@@ -283,10 +308,10 @@ {-# INLINE accurateSum #-} accurateSum :: (ExpField a, Foldable f, Ord a) => f (LogField a) -> LogField a accurateSum xs = LogField (theMax + log theSum)- where- LogField theMax = maximum xs--- compute @\log \sum_{x \in xs} \exp(x - theMax)@- theSum = F.foldl' (\acc (LogField x) -> acc + exp (x - theMax)) zero xs+ where+ LogField theMax = maximum xs+ -- compute @\log \sum_{x \in xs} \exp(x - theMax)@+ theSum = F.foldl' (\acc (LogField x) -> acc + exp (x - theMax)) zero xs -- | /O(n)/. Compute the product of a finite list of 'LogField's, -- being careful to avoid numerical error due to loss of precision.@@ -297,10 +322,9 @@ {-# INLINE accurateProduct #-} accurateProduct :: (ExpField a, Foldable f) => f (LogField a) -> LogField a accurateProduct = LogField . fst . F.foldr kahanPlus (zero, zero)- where- kahanPlus (LogField x) (t, c) =- let- y = x - c- t' = t + y- c' = (t' - t) - y- in (t', c')+ where+ kahanPlus (LogField x) (t, c) =+ let y = x - c+ t' = t + y+ c' = (t' - t) - y+ in (t', c')
src/NumHask/Data/Pair.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}@@ -10,24 +9,24 @@ -- | A Pair is *the* classical higher-kinded number but there is no canon. module NumHask.Data.Pair- ( Pair(..)- , pattern Pair- ) where+ ( Pair (..),+ pattern Pair,+ )+where -import qualified Prelude as P-import Prelude (Foldable, Traversable, Applicative, Monad, Functor(..), Semigroup(..), Monoid(..), Bounded(..), Eq(..), (<$>), (<*>), (&&))-import GHC.Generics (Generic) import Data.Functor.Classes+import GHC.Generics (Generic) import NumHask.Algebra.Abstract-import NumHask.Data.Integral import NumHask.Analysis.Metric+import NumHask.Data.Integral import NumHask.Data.Rational import Text.Show+import Prelude ((&&), (<$>), (<*>), Applicative, Bounded (..), Eq (..), Foldable, Functor (..), Monad, Monoid (..), Semigroup (..), Traversable)+import qualified Prelude as P -- $setup -- >>> :set -XNoImplicitPrelude -- >>> :set -XFlexibleContexts--- -- | A pair of a's, implemented as a tuple, but api represented as a Pair of a's. --@@ -43,7 +42,7 @@ -- Pair "a string" "pair mappended" -- -- As a Ring and Field class--- +-- -- >>> Pair 0 1 + zero -- Pair 0 1 -- >>> Pair 0 1 + Pair 2 3@@ -61,16 +60,16 @@ -- -- >>> Pair 1 2 .+ 3 -- Pair 4 5----newtype Pair a =- Pair' (a, a)+newtype Pair a+ = Pair' (a, a) deriving (Eq, Generic) -- | the preferred pattern pattern Pair :: a -> a -> Pair a-pattern Pair a b = Pair' (a,b)-{-# COMPLETE Pair#-}+pattern Pair a b = Pair' (a, b) +{-# COMPLETE Pair #-}+ instance (Show a) => Show (Pair a) where show (Pair a b) = "Pair " <> Text.Show.show a <> " " <> Text.Show.show b @@ -145,22 +144,23 @@ sign = unaryOp sign abs = unaryOp abs -instance (ExpField a, Normed a a) =>- Normed (Pair a) a where- normL1 (Pair a b) = normL1 a + normL1 b- normL2 (Pair a b) = sqrt (a ** (one + one) + b ** (one + one))+instance+ (ExpField a, Normed a a) =>+ Normed (Pair a) a+ where+ norm (Pair a b) = norm a + norm b instance (Subtractive a, Epsilon a) => Epsilon (Pair a) where epsilon = Pair epsilon epsilon nearZero (Pair a b) = nearZero a && nearZero b instance (ExpField a, Subtractive a, Normed a a) => Metric (Pair a) a where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance (Distributive a) => Distributive (Pair a) instance (Field a) => Field (Pair a)+ instance (IntegralDomain a) => IntegralDomain (Pair a) instance (ExpField a) => ExpField (Pair a) where@@ -174,17 +174,20 @@ type instance Actor (Pair a) = a instance (Additive a) => AdditiveAction (Pair a) where- (.+) r s = fmap (s+) r- (+.) s r = fmap (s+) r+ (.+) r s = fmap (s +) r+ (+.) s r = fmap (s +) r+ instance (Subtractive a) => SubtractiveAction (Pair a) where- (.-) r s = fmap (\x -> x - s) r- (-.) s r = fmap (\x -> x - s) r+ (.-) r s = fmap (\x -> x - s) r+ (-.) s r = fmap (\x -> x - s) r+ instance (Multiplicative a) => MultiplicativeAction (Pair a) where- (.*) r s = fmap (s*) r- (*.) s r = fmap (s*) r+ (.*) r s = fmap (s *) r+ (*.) s r = fmap (s *) r+ instance (Divisive a) => DivisiveAction (Pair a) where- (./) r s = fmap (/ s) r- (/.) s r = fmap (/ s) r+ (./) r s = fmap (/ s) r+ (/.) s r = fmap (/ s) r instance (JoinSemiLattice a) => JoinSemiLattice (Pair a) where (\/) = binOp (\/)@@ -204,12 +207,14 @@ instance (FromRatio a b) => FromRatio (Pair a) b where fromRatio x = P.pure (fromRatio x) -instance (Normed a a) =>- Normed (Pair a) (Pair a) where- normL1 = fmap normL1- normL2 = fmap normL2+instance+ (Normed a a) =>+ Normed (Pair a) (Pair a)+ where+ norm = fmap norm -instance (Subtractive a, Normed a a) =>- Metric (Pair a) (Pair a) where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+instance+ (Subtractive a, Normed a a) =>+ Metric (Pair a) (Pair a)+ where+ distance a b = norm (a - b)
src/NumHask/Data/Positive.hs view
@@ -9,32 +9,32 @@ import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Lattice import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring-import NumHask.Algebra.Abstract.Lattice import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Exception import qualified Prelude as P -newtype Positive a = Positive { unPositive :: a }+newtype Positive a = Positive {unPositive :: a} deriving- ( P.Show- , P.Eq- , P.Ord- , Additive- , Multiplicative- , Divisive- , Distributive- , IntegralDomain- , Field- , ExpField- , TrigField- , Integral- , Signed- , JoinSemiLattice- , MeetSemiLattice- , Epsilon+ ( P.Show,+ P.Eq,+ P.Ord,+ Additive,+ Multiplicative,+ Divisive,+ Distributive,+ IntegralDomain,+ Field,+ ExpField,+ TrigField,+ Integral,+ Signed,+ JoinSemiLattice,+ MeetSemiLattice,+ Epsilon ) -- not sure if this is correct or needed@@ -59,12 +59,16 @@ | a P.>= b = Positive (a - b) | P.otherwise = throw (NumHaskException "subtracting a larger positive") -instance (P.Ord a, QuotientField a P.Integer) =>- QuotientField (Positive a) (Positive P.Integer) where- properFraction (Positive a) = let (i,r) = properFraction a in (Positive i, Positive r)+instance+ (P.Ord a, QuotientField a P.Integer) =>+ QuotientField (Positive a) (Positive P.Integer)+ where+ properFraction (Positive a) = let (i, r) = properFraction a in (Positive i, Positive r) -instance (P.Ord a, UpperBoundedField a) =>- UpperBoundedField (Positive a) where+instance+ (P.Ord a, UpperBoundedField a) =>+ UpperBoundedField (Positive a)+ where infinity = Positive infinity instance (P.Ord a, UpperBoundedField a) => P.Bounded (Positive a) where@@ -72,11 +76,11 @@ maxBound = infinity -- Metric-instance (Normed a a) =>- Normed a (Positive a) where- normL1 a = Positive (normL1 a)- normL2 a = Positive (normL2 a)+instance+ (Normed a a) =>+ Normed a (Positive a)+ where+ norm a = Positive (norm a) instance (Subtractive a, Normed a a) => Metric a (Positive a) where- distanceL1 a b = Positive P.$ normL1 (a - b)- distanceL2 a b = Positive P.$ normL2 (a - b)+ distance a b = Positive P.$ norm (a - b)
src/NumHask/Data/Rational.hs view
@@ -5,41 +5,41 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wall #-} -- | Integral classes module NumHask.Data.Rational- ( Ratio(..)- , Rational- , ToRatio(..)- , ToRational- , toRational- , FromRatio(..)- , FromRational- , fromRational- , fromRational'- , fromBaseRational- -- * $integral_functionality- , reduce- , gcd+ ( Ratio (..),+ Rational,+ ToRatio (..),+ ToRational,+ toRational,+ FromRatio (..),+ FromRational,+ fromRational,+ fromRational',+ fromBaseRational,++ -- * \$integral_functionality+ reduce,+ gcd, ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64) import Data.Bool (bool)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8) import GHC.Float-import GHC.Natural (Natural(..))+import GHC.Natural (Natural (..))+import qualified GHC.Real import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Lattice import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring-import NumHask.Algebra.Abstract.Lattice import NumHask.Analysis.Metric import NumHask.Data.Integral-import Prelude (Int, Integer, Rational, (.))-import qualified GHC.Real+import Prelude ((.), Int, Integer, Rational) import qualified Prelude as P data Ratio a = !a :% !a deriving (P.Show)@@ -48,18 +48,18 @@ a == b | isRNaN a P.|| isRNaN b = P.False | P.otherwise = (x P.== x') P.&& (y P.== y')- where- (x:%y) = a- (x':%y') = b+ where+ (x :% y) = a+ (x' :% y') = b isRNaN :: (P.Eq a, Additive a) => Ratio a -> P.Bool isRNaN (x :% y) | x P.== zero P.&& y P.== zero = P.True | P.otherwise = P.False -instance (P.Ord a, Multiplicative a, Additive a) => P.Ord (Ratio a) where- (x:%y) <= (x':%y') = x * y' P.<= x' * y- (x:%y) < (x':%y') = x * y' P.< x' * y+instance (P.Ord a, Multiplicative a, Additive a) => P.Ord (Ratio a) where+ (x :% y) <= (x' :% y') = x * y' P.<= x' * y+ (x :% y) < (x' :% y') = x * y' P.< x' * y -- | These common constraints over the Ratio instances are due to the gcd algorithm. Subtractive is somewhat problematic with obtaining a `Ratio (Positive Integer)` which should be made possible. type GCDConstraints a = (P.Ord a, Signed a, Integral a, Subtractive a)@@ -77,26 +77,29 @@ negate (x :% y) = negate x :% y instance (GCDConstraints a) => Multiplicative (Ratio a) where- (x:%y) * (x':%y') = reduce (x * x') (y * y')+ (x :% y) * (x' :% y') = reduce (x * x') (y * y') one = one :% one -instance (GCDConstraints a) =>- Divisive (Ratio a) where+instance+ (GCDConstraints a) =>+ Divisive (Ratio a)+ where recip (x :% y) | sign x P.== negate one = negate y :% negate x | P.otherwise = y :% x -instance (GCDConstraints a) => Distributive (Ratio a)+instance (GCDConstraints a) => Distributive (Ratio a) instance (GCDConstraints a) => IntegralDomain (Ratio a) instance (GCDConstraints a) => Field (Ratio a) instance (GCDConstraints a, GCDConstraints b, ToInteger a, Field a, FromIntegral b a) => QuotientField (Ratio a) b where- properFraction (n :% d) = let (w,r) = quotRem n d in (fromIntegral_ w,r:%d)+ properFraction (n :% d) = let (w, r) = quotRem n d in (fromIntegral_ w, r :% d) -instance (GCDConstraints a, Distributive a, IntegralDomain a) =>+instance+ (GCDConstraints a, Distributive a, IntegralDomain a) => UpperBoundedField (Ratio a) instance (GCDConstraints a, Field a) => LowerBoundedField (Ratio a)@@ -109,12 +112,10 @@ abs (n :% d) = abs n :% abs d instance (GCDConstraints a) => Normed (Ratio a) (Ratio a) where- normL1 = abs- normL2 = abs+ norm = abs instance (GCDConstraints a) => Metric (Ratio a) (Ratio a) where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)+ distance a b = norm (a - b) instance (GCDConstraints a, MeetSemiLattice a) => Epsilon (Ratio a) @@ -194,13 +195,13 @@ fromBaseRational (n GHC.Real.:% d) = n :% d instance FromRatio Double Integer where- fromRatio (n:%d)= rationalToDouble n d+ fromRatio (n :% d) = rationalToDouble n d instance FromRatio Float Integer where- fromRatio (n:%d)= rationalToFloat n d+ fromRatio (n :% d) = rationalToFloat n d instance FromRatio Rational Integer where- fromRatio (n:%d) = n GHC.Real.% d+ fromRatio (n :% d) = n GHC.Real.% d instance FromRatio (Ratio Integer) Integer where fromRatio = P.id@@ -212,7 +213,9 @@ fromRational = fromRatio . fromBaseRational instance FromRational Double+ instance FromRational Float+ instance FromRational Rational -- | Given that fromRational is reserved, fromRational' provides general conversion between numhask rationals.@@ -225,23 +228,24 @@ instance (GCDConstraints a) => MeetSemiLattice (Ratio a) where (/\) = P.max --- * $integral_functions+-- * \$integral_functions -- integral functionality is largely based on GHC.Real --+ -- | 'reduce' is a subsidiary function used only in this module. -- It normalises a ratio by dividing both numerator and denominator by -- their greatest common divisor.-reduce- :: (P.Eq a, Subtractive a, Signed a, Integral a) => a -> a -> Ratio a+reduce ::+ (P.Eq a, Subtractive a, Signed a, Integral a) => a -> a -> Ratio a reduce x y | x P.== zero P.&& y P.== zero = zero :% zero | z P.== zero = one :% zero | P.otherwise = (x `quot` z) % (y `quot` z)- where- z = gcd x y- n % d- | sign d P.== negate one = negate n :% negate d- | P.otherwise = n :% d+ where+ z = gcd x y+ n % d+ | sign d P.== negate one = negate n :% negate d+ | P.otherwise = n :% d -- | @'gcd' x y@ is the non-negative factor of both @x@ and @y@ of which -- every common factor of @x@ and @y@ is also a factor; for example@@ -254,7 +258,7 @@ -- necessarily is if the other is @0@ or @'minBound'@) for such types. gcd :: (P.Eq a, Signed a, Integral a) => a -> a -> a gcd x y = gcd' (abs x) (abs y)- where- gcd' a b- | b P.== zero = a- | P.otherwise = gcd' b (a `rem` b)+ where+ gcd' a b+ | b P.== zero = a+ | P.otherwise = gcd' b (a `rem` b)
src/NumHask/Data/Wrapped.hs view
@@ -9,49 +9,51 @@ import NumHask.Algebra.Abstract.Additive import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Group+import NumHask.Algebra.Abstract.Lattice import NumHask.Algebra.Abstract.Multiplicative import NumHask.Algebra.Abstract.Ring-import NumHask.Algebra.Abstract.Lattice-import NumHask.Algebra.Abstract.Group import NumHask.Analysis.Metric import NumHask.Data.Integral import NumHask.Data.Rational import qualified Prelude as P -newtype Wrapped a = Wrapped { unWrapped :: a }+newtype Wrapped a = Wrapped {unWrapped :: a} deriving- ( P.Show- , P.Eq- , P.Ord- , Magma- , Idempotent- , Additive- , Subtractive- , Multiplicative- , Divisive- , Distributive- , IntegralDomain- , InvolutiveRing- , StarSemiring- , KleeneAlgebra- , Field- , ExpField- , TrigField- , Integral- , Signed- , MeetSemiLattice- , JoinSemiLattice- , Epsilon- , UpperBoundedField- , LowerBoundedField+ ( P.Show,+ P.Eq,+ P.Ord,+ Magma,+ Idempotent,+ Additive,+ Subtractive,+ Multiplicative,+ Divisive,+ Distributive,+ IntegralDomain,+ InvolutiveRing,+ StarSemiring,+ KleeneAlgebra,+ Field,+ ExpField,+ TrigField,+ Integral,+ Signed,+ MeetSemiLattice,+ JoinSemiLattice,+ Epsilon,+ UpperBoundedField,+ LowerBoundedField ) -- not sure if this is correct or needed type role Wrapped representational -instance (P.Ord a, QuotientField a P.Integer) =>- QuotientField (Wrapped a) (Wrapped P.Integer) where- properFraction (Wrapped a) = let (i,r) = properFraction a in (Wrapped i, Wrapped r)+instance+ (P.Ord a, QuotientField a P.Integer) =>+ QuotientField (Wrapped a) (Wrapped P.Integer)+ where+ properFraction (Wrapped a) = let (i, r) = properFraction a in (Wrapped i, Wrapped r) instance (FromIntegral a b) => FromIntegral (Wrapped a) b where fromIntegral_ a = Wrapped (fromIntegral_ a)@@ -66,9 +68,7 @@ toRatio (Wrapped a) = toRatio a instance (Normed a b) => Normed (Wrapped a) (Wrapped b) where- normL1 (Wrapped a) = Wrapped (normL1 a)- normL2 (Wrapped a) = Wrapped (normL2 a)+ norm (Wrapped a) = Wrapped (norm a) instance (Metric a b) => Metric (Wrapped a) (Wrapped b) where- distanceL1 (Wrapped a) (Wrapped b) = Wrapped (distanceL1 a b)- distanceL2 (Wrapped a) (Wrapped b) = Wrapped (distanceL2 a b)+ distance (Wrapped a) (Wrapped b) = Wrapped (distance a b)
src/NumHask/Exception.hs view
@@ -1,15 +1,16 @@ {-# OPTIONS_GHC -Wall #-} module NumHask.Exception- ( NumHaskException(..)- , throw- ) where+ ( NumHaskException (..),+ throw,+ )+where -import qualified Prelude as P import Control.Exception import Data.Typeable (Typeable)+import qualified Prelude as P -newtype NumHaskException = NumHaskException { errorMessage :: P.String }+newtype NumHaskException = NumHaskException {errorMessage :: P.String} deriving (P.Show, Typeable) instance Exception NumHaskException
+ src/NumHask/Prelude.hs view
@@ -0,0 +1,84 @@+{-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_HADDOCK prune #-}++-- | Combines 'Protolude' and 'numhask'.+module NumHask.Prelude+ ( -- * NumHask+ -- $instances+ module NumHask.Algebra.Abstract.Action,+ module NumHask.Algebra.Abstract.Additive,+ module NumHask.Algebra.Abstract.Field,+ module NumHask.Algebra.Abstract.Group,+ module NumHask.Algebra.Abstract.Lattice,+ module NumHask.Algebra.Abstract.Module,+ module NumHask.Algebra.Abstract.Multiplicative,+ module NumHask.Algebra.Abstract.Ring,+ module NumHask.Analysis.Metric,+ module NumHask.Data.Complex,+ module NumHask.Data.Integral,+ module NumHask.Data.LogField,+ module NumHask.Data.Rational,+ module NumHask.Data.Pair,+ module NumHask.Data.Positive,+ Natural (..),+ module NumHask.Exception,++ -- * Backend+ -- $backend+ Category (..),+ module Protolude,+ module Data.Biapplicative,+ module Control.Monad.Morph,+ module Data.Functor.Constant,+ pack,+ unpack,+ -- | Using different types for numbers requires RebindableSyntax. This then removes all sorts of base-level stuff that has to be put back in.+ fromString,+ fail,+ ifThenElse,+ fromList,+ fromListN,+ )+where++import Control.Category (Category (..))+import Control.Monad (fail)+import Control.Monad.Morph+import Data.Biapplicative+import Data.Functor.Constant+import Data.String+import Data.Text (pack, unpack)+import GHC.Exts+import GHC.Natural (Natural (..))+import NumHask.Algebra.Abstract.Action+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Group+import NumHask.Algebra.Abstract.Lattice+import NumHask.Algebra.Abstract.Module+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Analysis.Metric+import NumHask.Data.Complex+import NumHask.Data.Integral+import NumHask.Data.LogField+import NumHask.Data.Pair+import NumHask.Data.Positive+import NumHask.Data.Rational+import NumHask.Exception+import Protolude hiding ((*), (**), (+), (-), (.), (/), (<<$>>), (<<*>>), Complex (..), Integral (..), Product (..), Ratio, Rep, Semiring (..), Sum (..), (^), (^^), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cis, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, imagPart, infinity, log, logBase, magnitude, mkPolar, negate, odd, phase, pi, polar, product, properFraction, realPart, recip, reduce, round, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, trans, truncate, zero)++-- $backend+-- NumHask imports Protolude as a starting prelude.+--+-- In addition, 'id' is imported (protolude uses 'identity')++-- $instances+-- NumHask replaces much of the 'Num' and 'Real' heirarchies in protolude & base.+--+-- Instances for 'Int', 'Integer', 'Float', 'Double', 'Bool', 'Complex' and 'Natural'are supplied.++-- | rebindable syntax splats this, and I'm not sure where it exists in GHC land+ifThenElse :: Bool -> a -> a -> a+ifThenElse True x _ = x+ifThenElse False _ y = y