packages feed

numhask 0.8.1.0 → 0.9.0.0

raw patch · 11 files changed

+269/−213 lines, 11 files

Files

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:-    .-    ![nh](docs/other/nh.svg)-    .-    == 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:+  .+  ![nh](docs/other/nh.svg)+  .+  == 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 :% _) =