numhask 0.8.1.0 → 0.9.0.0
raw patch · 11 files changed
+269/−213 lines, 11 files
Files
- ChangeLog.md +5/−0
- numhask.cabal +38/−61
- src/NumHask.hs +61/−21
- src/NumHask/Algebra/Additive.hs +11/−7
- src/NumHask/Algebra/Field.hs +84/−77
- src/NumHask/Algebra/Lattice.hs +2/−2
- src/NumHask/Algebra/Metric.hs +21/−6
- src/NumHask/Algebra/Module.hs +35/−20
- src/NumHask/Algebra/Multiplicative.hs +11/−7
- src/NumHask/Data/Complex.hs +0/−5
- src/NumHask/Data/Rational.hs +1/−7
ChangeLog.md view
@@ -1,3 +1,8 @@+0.9.0+===+* Removed bounded classes.+* Moved operators outside of class definitions where possible. + 0.8.0 =====
numhask.cabal view
@@ -1,71 +1,47 @@-cabal-version: 2.4-name: numhask-version: 0.8.1.0-synopsis:- A numeric class hierarchy.+cabal-version: 2.4+name: numhask+version: 0.9.0.0+synopsis: A numeric class hierarchy. description:- This package provides alternative numeric classes over Prelude.- .- The numeric class constellation looks somewhat like:- .- - .- == Usage- .- >>> {-# LANGUAGE RebindableSyntax #-}- >>> import NumHask.Prelude- .- See "NumHask" for a detailed overview.--category:- mathematics-homepage:- https://github.com/tonyday567/numhask#readme-bug-reports:- https://github.com/tonyday567/numhask/issues-author:- Tony Day-maintainer:- tonyday567@gmail.com-copyright:- Tony Day-license:- BSD-3-Clause-license-file:- LICENSE-build-type:- Simple-tested-with:- GHC ==8.8.4- || ==8.10.4- || ==9.0.1- || ==9.2.0.20210821-extra-doc-files:- other/*.svg+ This package provides alternative numeric classes over Prelude.+ .+ The numeric class constellation looks somewhat like:+ .+ + .+ == Usage+ .+ >>> {-# LANGUAGE RebindableSyntax #-}+ >>> import NumHask.Prelude+ .+ See "NumHask" for a detailed overview. -extra-source-files:- ChangeLog.md+category: mathematics+homepage: https://github.com/tonyday567/numhask#readme+bug-reports: https://github.com/tonyday567/numhask/issues+author: Tony Day+maintainer: tonyday567@gmail.com+copyright: Tony Day+license: BSD-3-Clause+license-file: LICENSE+build-type: Simple+tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.2.1+extra-doc-files: other/*.svg+extra-source-files: ChangeLog.md source-repository head- type:- git- location:- https://github.com/tonyday567/numhask- subdir:- numhask+ type: git+ location: https://github.com/tonyday567/numhask+ subdir: numhask+ library- hs-source-dirs:- src+ hs-source-dirs: src ghc-options:- -Wall- -Wcompat- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wredundant-constraints- -fwrite-ide-info+ -Wall -Wcompat -Wincomplete-record-updates+ -Wincomplete-uni-patterns -Wredundant-constraints -fwrite-ide-info -hiedir=.hie- build-depends:- base >=4.7 && <5++ build-depends: base >=4.7 && <5 exposed-modules: NumHask NumHask.Algebra.Additive@@ -81,5 +57,6 @@ NumHask.Data.Rational NumHask.Exception NumHask.Prelude+ other-modules: default-language: Haskell2010
src/NumHask.hs view
@@ -17,18 +17,56 @@ -- * Extensions -- $extensions - -- * Exports- module NumHask.Algebra.Additive,- module NumHask.Algebra.Multiplicative,+ -- * Additive+ Additive (..),+ sum,+ Subtractive (..),+ (-),++ -- * Multiplicative+ Multiplicative (..),+ product,+ Divisive (..),+ (/),++ -- * Ring module NumHask.Algebra.Ring,- module NumHask.Algebra.Field,++ -- * Field+ ExpField (..),+ logBase,+ sqrt,+ Field,+ QuotientField (..),+ round,+ ceiling,+ floor,+ truncate,+ TrigField (..),+ infinity,+ negInfinity,+ nan,+ half,++ -- * Lattice module NumHask.Algebra.Lattice,++ -- * Module module NumHask.Algebra.Module,++ -- * Metric module NumHask.Algebra.Metric,- module NumHask.Algebra.Group,++ -- * Complex module NumHask.Data.Complex,++ -- * Integral module NumHask.Data.Integral,++ -- * Rational module NumHask.Data.Rational,++ -- * Exceptions module NumHask.Exception, ) where@@ -37,26 +75,23 @@ ( Additive (..), Subtractive (..), sum,+ (-), ) import NumHask.Algebra.Field ( ExpField (..), Field,- LowerBoundedField (..), QuotientField (..), TrigField (..),- UpperBoundedField (..),+ ceiling,+ floor, half,- )-import NumHask.Algebra.Group- ( AbelianGroup,- Absorbing (..),- Associative,- Commutative,- Group,- Idempotent,- Invertible (..),- Magma (..),- Unital (..),+ infinity,+ logBase,+ nan,+ negInfinity,+ round,+ sqrt,+ truncate, ) import NumHask.Algebra.Lattice ( BoundedJoinSemiLattice (..),@@ -83,11 +118,16 @@ Module, MultiplicativeAction (..), SubtractiveAction (..),+ (*.),+ (+.),+ (-.),+ (/.), ) import NumHask.Algebra.Multiplicative ( Divisive (..), Multiplicative (..), product,+ (/), ) import NumHask.Algebra.Ring ( Distributive,@@ -142,10 +182,10 @@ -- -- >>> :set -XNoRebindableSyntax -- >>> :t 1--- 1 :: Num a => a+-- 1 :: Num p => p -- -- >>> :t 1.0--- 1.0 :: Fractional a => a+-- 1.0 :: Fractional p => p -- -- With RebindableSyntax (which also switches NoImplicitPrelude on) literal numbers change to the numhask types, 'FromInteger' and 'FromRational': --@@ -177,7 +217,7 @@ -- Principles that have guided design include: -- -- - __/balanced class density/__. The numeric heirarchy begins with addition and multiplication,--- choosing not to build from a 'Magma' base. Whilst not being as principled as other approaches, this circumvents the instance explosion problems of Haskell whilst maintaining clarity of class purpose.+-- choosing not to build from a Magma base. Whilst not being as principled as other approaches, this circumvents the instance explosion problems of Haskell whilst maintaining clarity of class purpose. -- -- - __/operator-first/__. In most cases, a class exists to define useful operators. -- The exceptions are 'Distributive', 'Ring' and 'Field', which are collections of operators
src/NumHask/Algebra/Additive.hs view
@@ -1,17 +1,19 @@ {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -Wno-unused-imports #-} -- | Additive classes module NumHask.Algebra.Additive ( Additive (..), sum, Subtractive (..),+ (-), ) where 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 Prelude (Bool, Double, Float, Int, Integer, fromInteger) import qualified Prelude as P -- $setup@@ -56,15 +58,17 @@ -- -- >>> negate 1 -- -1------ >>> 1 - 2--- -1 class (Additive a) => Subtractive a where negate :: a -> a - infixl 6 -- (-) :: a -> a -> a- (-) a b = a + negate b+infixl 6 -++-- | minus+--+-- >>> 1 - 2+-- -1+(-) :: (Subtractive a) => a -> a -> a+(-) a b = a + negate b instance Additive Double where (+) = (P.+)
src/NumHask/Algebra/Field.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -10,19 +9,27 @@ module NumHask.Algebra.Field ( Field, ExpField (..),+ logBase,+ sqrt, QuotientField (..),- UpperBoundedField (..),- LowerBoundedField (..),+ round,+ ceiling,+ floor,+ truncate,+ infinity,+ negInfinity,+ nan, TrigField (..), half, ) where import Data.Bool (bool)-import NumHask.Algebra.Additive (Additive (..), Subtractive (..))+import NumHask.Algebra.Additive (Additive (..), Subtractive (..), (-)) import NumHask.Algebra.Multiplicative- ( Divisive ((/)),+ ( Divisive (..), Multiplicative (..),+ (/), ) import NumHask.Algebra.Ring (Distributive, two) import NumHask.Data.Integral (Integral, even)@@ -81,13 +88,23 @@ where exp :: a -> a log :: a -> a- logBase :: a -> a -> a- logBase a b = log b / log a (**) :: a -> a -> a (**) a b = exp (log a * b)- sqrt :: a -> a- sqrt a = a ** (one / (one + one)) +-- | log to the base of+--+-- >>> logBase 2 8+-- 2.9999999999999996+logBase :: (ExpField a) => a -> a -> a+logBase a b = log b / log a++-- | square root+--+-- >>> sqrt 4+-- 2.0+sqrt :: (ExpField a) => a -> a+sqrt a = a ** (one / (one + one))+ instance ExpField P.Double where exp = P.exp log = P.log@@ -101,9 +118,6 @@ instance ExpField b => ExpField (a -> b) where exp f = exp . f log f = log . f- logBase f f' a = logBase (f a) (f' a)- f ** f' = \a -> f a ** f' a- sqrt f = sqrt . f -- | Conversion from a 'Field' to a 'NumHask.Algebra.Ring' --@@ -114,35 +128,55 @@ class (Field a, Multiplicative b, Additive b) => QuotientField a b where properFraction :: a -> (b, a) - round :: 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+-- | round to the nearest integral+--+-- Exact ties are managed by rounding down ties if the whole component is even.+--+-- >>> round (1.5 :: Double) :: Int+-- 2+--+-- >>> round (2.5 :: Double) :: Int+-- 2+round :: (P.Ord a, P.Ord b, QuotientField a 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 - ceiling :: a -> b- default ceiling :: (P.Ord a) => a -> b- ceiling x = bool n (n + one) (r P.>= zero)- where- (n, r) = properFraction x+-- | supply the next upper whole component+--+-- >>> ceiling (1.001 :: Double) :: Int+-- 2+ceiling :: (P.Ord a, QuotientField a b) => a -> b+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+-- | supply the previous lower whole component+--+-- >>> floor (1.001 :: Double) :: Int+-- 1+floor :: (P.Ord a, QuotientField a b, Subtractive b) => a -> b+floor x = bool n (n - one) (r P.< zero)+ where+ (n, r) = properFraction x - truncate :: a -> b- default truncate :: (P.Ord a) => a -> b- truncate x = bool (ceiling x) (floor x) (x P.> zero)+-- | supply the whole component closest to zero+--+-- >>> floor (-1.001 :: Double) :: Int+-- -2+--+-- >>> truncate (-1.001 :: Double) :: Int+-- -1+truncate :: (P.Ord a, QuotientField a b, Subtractive b) => a -> b+truncate x = bool (ceiling x) (floor x) (x P.> zero) instance QuotientField P.Float P.Integer where properFraction = P.properFraction@@ -161,53 +195,26 @@ where frac a = properFraction @b @c (f a) - round f = round . f-- ceiling f = ceiling . f-- floor f = floor . f-- truncate f = truncate . f---- | A bounded field introduces the concepts of infinity and NaN.+-- | A field introduces the concept of infinity. -- -- > one / zero + infinity == infinity -- > infinity + a == infinity -- > 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- infinity :: a- infinity = one / zero-- nan :: a- nan = zero / zero--instance UpperBoundedField P.Float--instance UpperBoundedField P.Double--instance UpperBoundedField b => UpperBoundedField (a -> b) where- infinity _ = infinity- nan _ = nan---- | Negative infinity.-class- (Subtractive a, Field a) =>- LowerBoundedField a- where- negInfinity :: a- negInfinity = negate (one / zero)--instance LowerBoundedField P.Float+infinity :: (Field a) => a+infinity = one / zero -instance LowerBoundedField P.Double+-- |+--+-- Note the law:+-- -- > zero / zero != nan+nan :: (Field a) => a+nan = zero / zero -instance LowerBoundedField b => LowerBoundedField (a -> b) where- negInfinity _ = negInfinity+-- | negative infinity+negInfinity :: (Field a) => a+negInfinity = negate infinity -- | Trigonometric Field class
src/NumHask/Algebra/Lattice.hs view
@@ -29,8 +29,8 @@ import GHC.Word (Word) import NumHask.Algebra.Additive (zero) import NumHask.Algebra.Field- ( LowerBoundedField (negInfinity),- UpperBoundedField (infinity),+ ( infinity,+ negInfinity, ) -- | A algebraic structure with element joins: See [Semilattice](http://en.wikipedia.org/wiki/Semilattice)
src/NumHask/Algebra/Metric.hs view
@@ -14,6 +14,8 @@ polar, coord, Epsilon (..),+ nearZero,+ aboutEqual, (~=), ) where@@ -23,7 +25,7 @@ import Data.Word (Word16, Word32, Word64, Word8) import GHC.Generics (Generic) import GHC.Natural (Natural (..))-import NumHask.Algebra.Additive (Additive (zero), Subtractive (..))+import NumHask.Algebra.Additive (Additive (zero), Subtractive (..), (-)) import NumHask.Algebra.Lattice (MeetSemiLattice, meetLeq) import NumHask.Algebra.Module (MultiplicativeAction ((.*))) import NumHask.Algebra.Multiplicative (Multiplicative (one))@@ -36,6 +38,11 @@ ) import qualified Prelude as P +-- $setup+--+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude+ -- | 'signum' from base is not an operator name in numhask and is replaced by 'sign'. Compare with 'Norm' where there is a change in codomain. -- -- > abs a * sign a == a@@ -249,15 +256,23 @@ epsilon :: a epsilon = zero - nearZero :: a -> Bool- nearZero a = epsilon `meetLeq` a && epsilon `meetLeq` negate a+-- | are we near zero?+--+-- >>> nearZero (epsilon :: Double)+-- True+nearZero :: (Epsilon a) => a -> Bool+nearZero a = epsilon `meetLeq` a && epsilon `meetLeq` negate a - aboutEqual :: a -> a -> Bool- aboutEqual a b = nearZero $ a - b+-- | Approximate equality+aboutEqual :: (Epsilon a) => a -> a -> Bool+aboutEqual a b = nearZero $ a - b infixl 4 ~= --- | About equal.+-- | About equal operator.+--+-- >>> (1.0 + epsilon) ~= (1.0 :: Double)+-- True (~=) :: (Epsilon a) => a -> a -> Bool (~=) = aboutEqual
src/NumHask/Algebra/Module.hs view
@@ -5,26 +5,21 @@ -- | Algebra for Modules module NumHask.Algebra.Module ( AdditiveAction (..),+ (+.), SubtractiveAction (..),+ (-.), MultiplicativeAction (..),+ (*.), DivisiveAction (..),+ (/.), Module, ) where -import NumHask.Algebra.Additive (Additive, Subtractive)-import NumHask.Algebra.Multiplicative (Divisive, Multiplicative)+import NumHask.Algebra.Additive (Additive, Subtractive, negate)+import NumHask.Algebra.Multiplicative (Divisive, Multiplicative, recip) import NumHask.Algebra.Ring (Distributive)---- $setup------ >>> :set -XRebindableSyntax--- >>> :set -XFlexibleContexts--- >>> :set -XFlexibleInstances--- >>> :set -XScopedTypeVariables--- >>> :set -XMultiParamTypeClasses--- >>> import NumHask.Prelude--- >>> import Prelude (Int, fmap)+import Prelude (flip) -- | Additive Action class@@ -35,9 +30,14 @@ infixl 6 .+ (.+) :: a -> m -> m - infixl 6 +.- (+.) :: m -> a -> m+infixl 6 +. +-- | flipped additive action+--+-- > (+.) == flip (.+)+(+.) :: (AdditiveAction m a) => m -> a -> m+(+.) = flip (.+)+ -- | Subtractive Action class (Subtractive a) =>@@ -47,9 +47,14 @@ infixl 6 .- (.-) :: a -> m -> m - infixl 6 -.- (-.) :: m -> a -> m+infixl 6 -. +-- | right scalar subtraction+--+-- > (-.) == (+.) . negate+(-.) :: (AdditiveAction m a, Subtractive a) => m -> a -> m+a -. b = a +. negate b+ -- | Multiplicative Action class (Multiplicative a) =>@@ -58,9 +63,15 @@ where infixl 7 .* (.*) :: a -> m -> m- infixl 7 *.- (*.) :: m -> a -> m +infixl 7 *.++-- | flipped multiplicative action+--+-- > (*.) == flip (.*)+(*.) :: (MultiplicativeAction m a) => m -> a -> m+(*.) = flip (.*)+ -- | Divisive Action class (Divisive a) =>@@ -69,8 +80,12 @@ where infixl 7 ./ (./) :: a -> m -> m- infixl 7 /.- (/.) :: m -> a -> m++-- | right scalar division+--+-- > (/.) == (*.) . recip+(/.) :: (MultiplicativeAction m a, Divisive a) => m -> a -> m+a /. b = a *. recip b -- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module> --
src/NumHask/Algebra/Multiplicative.hs view
@@ -1,17 +1,19 @@ {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -Wno-unused-imports #-} -- | Multiplicative classes module NumHask.Algebra.Multiplicative ( Multiplicative (..), product, Divisive (..),+ (/), ) where 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 Prelude (Double, Float, Int, Integer, fromInteger, fromRational) import qualified Prelude as P -- $setup@@ -58,15 +60,17 @@ -- -- >>> recip 2.0 -- 0.5------ >>> 1 / 2--- 0.5 class (Multiplicative a) => Divisive a where recip :: a -> a - infixl 7 /- (/) :: a -> a -> a- (/) a b = a * recip b+infixl 7 /++-- | divide+--+-- >>> 1 / 2+-- 0.5+(/) :: (Divisive a) => a -> a -> a+(/) a b = a * recip b instance Multiplicative Double where (*) = (P.*)
src/NumHask/Data/Complex.hs view
@@ -121,7 +121,6 @@ Epsilon (Complex a) where epsilon = epsilon :+ epsilon- nearZero (a :+ b) = nearZero a && nearZero b instance (Field a) => Field (Complex a) @@ -141,10 +140,6 @@ instance (Distributive a, Subtractive a) => InvolutiveRing (Complex a) where adj (a :+ b) = a :+ negate b--instance (UpperBoundedField a, Subtractive a) => UpperBoundedField (Complex a)--instance (LowerBoundedField a) => LowerBoundedField (Complex a) instance (JoinSemiLattice a) => JoinSemiLattice (Complex a) where (\/) (ar :+ ai) (br :+ bi) = (ar \/ br) :+ (ai \/ bi)
src/NumHask/Data/Rational.hs view
@@ -91,14 +91,8 @@ instance (P.Ord a, Signed a, Integral a, Ring a) => Field (Ratio a) -instance (P.Ord a, Signed a, Integral a, Ring a, P.Ord b, Signed b, Integral b, Ring b, Field a, FromIntegral b a) => QuotientField (Ratio a) b where+instance (P.Ord a, Signed a, Integral a, Ring a, Signed b, FromIntegral b a) => QuotientField (Ratio a) b where properFraction (n :% d) = let (w, r) = quotRem n d in (fromIntegral w, r :% d)--instance- (P.Ord a, Signed a, Integral a, Ring a, Distributive a) =>- UpperBoundedField (Ratio a)--instance (P.Ord a, Signed a, Integral a, Field a) => LowerBoundedField (Ratio a) instance (P.Ord a, Signed a, Integral a, Ring a) => Signed (Ratio a) where sign (n :% _) =