numhask 0.10.1.1 → 0.11.0.1
raw patch · 19 files changed
+706/−672 lines, 19 filesdep ~QuickCheckdep ~base
Dependency ranges changed: QuickCheck, base
Files
- ChangeLog.md +16/−0
- numhask.cabal +88/−23
- other/nh.svg +8/−8
- src/NumHask.hs +62/−44
- src/NumHask/Algebra/Action.hs +112/−0
- src/NumHask/Algebra/Additive.hs +3/−5
- src/NumHask/Algebra/Field.hs +28/−54
- src/NumHask/Algebra/Group.hs +2/−10
- src/NumHask/Algebra/Lattice.hs +4/−28
- src/NumHask/Algebra/Metric.hs +268/−198
- src/NumHask/Algebra/Module.hs +0/−97
- src/NumHask/Algebra/Multiplicative.hs +2/−3
- src/NumHask/Algebra/Ring.hs +4/−52
- src/NumHask/Data/Complex.hs +54/−90
- src/NumHask/Data/Integral.hs +10/−10
- src/NumHask/Data/Rational.hs +22/−33
- src/NumHask/Exception.hs +0/−2
- src/NumHask/Prelude.hs +23/−7
- test/doctests.hs +0/−8
ChangeLog.md view
@@ -1,3 +1,19 @@+0.11.0.0+===++* TypeFamilies introduced replacing FunDep usage for QuotientField, AdditiveAction, MultiplicativeAction, Basis. Classes go from Multi-parameter to single.+* EuclideanPair introduced as an intended DerivingVia support for 2 dimensional Basis & Direction instances. +* Complex modified to use EuclideanPair. Underlying representation changed to tuple and (+:) constructor as a top-level function.+* Action class operators changed from (.\*) to (|\*), and (\*.) to (\*|) etc.+* Ring, Field, Distributive & Module become type synonyms (were classes).+* Added Basis class replacing Norm & Signed+* extra type synonyms added for Basis specialisations: Absolute, Sign, EndoBased.+* abs becomes top-level function (previously method of Norm).+* sign removed and replaced with signum, mirroring Num.+* aboutEqual & nearZero moved outside Epsilon class definition.+* rationalised Language pragmas around GHC2021+* introduced QuotientField instance for Complex & EuclideanPair without Ord constraint.+ 0.10.0 === * Moved operators back in.
numhask.cabal view
@@ -1,6 +1,6 @@-cabal-version: 2.4+cabal-version: 3.0 name: numhask-version: 0.10.1.1+version: 0.11.0.1 synopsis: A numeric class hierarchy. description: This package provides alternative numeric classes over Prelude.@@ -11,6 +11,7 @@ . == Usage .+ >>> {-# LANGUAGE GHC2021 #-} >>> {-# LANGUAGE RebindableSyntax #-} >>> import NumHask.Prelude .@@ -26,27 +27,100 @@ license-file: LICENSE build-type: Simple tested-with:- GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.2.5 || ==9.4.4+ GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.5 || ==9.6.2 -extra-doc-files: other/*.svg-extra-source-files: ChangeLog.md+extra-doc-files: other/*.svg,+ ChangeLog.md source-repository head type: git location: https://github.com/tonyday567/numhask subdir: numhask -library- hs-source-dirs: src- ghc-options:- -Wall -Wcompat -Wincomplete-record-updates- -Wincomplete-uni-patterns -Wredundant-constraints+common ghc2021-stanza+ if impl(ghc >=9.2)+ default-language:+ GHC2021+ if impl(ghc <9.2)+ default-language:+ Haskell2010+ default-extensions:+ BangPatterns+ BinaryLiterals+ ConstrainedClassMethods+ ConstraintKinds+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveLift+ DeriveTraversable+ DoAndIfThenElse+ EmptyCase+ EmptyDataDecls+ EmptyDataDeriving+ ExistentialQuantification+ ExplicitForAll+ FlexibleContexts+ FlexibleInstances+ ForeignFunctionInterface+ GADTSyntax+ GeneralisedNewtypeDeriving+ HexFloatLiterals+ ImplicitPrelude+ InstanceSigs+ KindSignatures+ MonomorphismRestriction+ MultiParamTypeClasses+ NamedFieldPuns+ NamedWildCards+ NumericUnderscores+ PatternGuards+ PolyKinds+ PostfixOperators+ RankNTypes+ RelaxedPolyRec+ ScopedTypeVariables+ StandaloneDeriving+ StarIsType+ TraditionalRecordSyntax+ TupleSections+ TypeApplications+ TypeOperators+ TypeSynonymInstances+ if impl(ghc <9.2) && impl(ghc >=8.10)+ default-extensions:+ ImportQualifiedPost+ StandaloneKindSignatures +common ghc-options-stanza+ ghc-options:+ -Wall+ -Wcompat+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wredundant-constraints+ -Widentities+ -Wpartial-fields if impl(ghc >=8.8)- ghc-options: -fwrite-ide-info -hiedir=.hie+ ghc-options:+ -fwrite-ide-info+ -hiedir=.hie - x-docspec-extra-packages: QuickCheck- build-depends: base >=4.7 && <5+library+ import: ghc2021-stanza+ import: ghc-options-stanza+ hs-source-dirs: src+ default-extensions:+ RebindableSyntax+ -- keeping ormolu happy+ if impl(ghc >=8.10)+ default-extensions:+ NoImportQualifiedPost+ build-depends:+ base >=4.7 && <5,+ -- keeping cabal-docspec happy+ QuickCheck >=2.14 && <3 exposed-modules: NumHask NumHask.Algebra.Additive@@ -54,7 +128,7 @@ NumHask.Algebra.Group NumHask.Algebra.Lattice NumHask.Algebra.Metric- NumHask.Algebra.Module+ NumHask.Algebra.Action NumHask.Algebra.Multiplicative NumHask.Algebra.Ring NumHask.Data.Complex@@ -64,13 +138,4 @@ NumHask.Prelude other-modules:- default-language: Haskell2010 -test-suite doctests- type: exitcode-stdio-1.0- main-is: doctests.hs- hs-source-dirs: test- default-language: Haskell2010- build-depends:- , base- , QuickCheck
other/nh.svg view
@@ -1,25 +1,25 @@-<svg xmlns="http://www.w3.org/2000/svg" width="1044.6129846153847" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0.5000399999999985 -324.5 678.99844 325.0" height="500.0"><style>svg {+<svg height="500" width="500" viewBox="-50 -350 500 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>svg { color-scheme: light dark; } { .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {- fill: #0d0d0d;+ fill: rgb(5%, 5%, 5%); } .ticklines g, .tickglyph g, .legendBorder g {- stroke: #0d0d0d;+ stroke: rgb(5%, 5%, 5%); } .legendBorder g {- fill: #f0f0f0;+ fill: rgb(94%, 94%, 94%); } } @media (prefers-color-scheme:dark) { .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {- fill: #f0f0f0;+ fill: rgb(94%, 94%, 94%); } .ticklines g, .tickglyph g, .legendBorder g {- stroke: #f0f0f0;+ stroke: rgb(94%, 94%, 94%); } .legendBorder g {- fill: #0d0d0d;+ fill: rgb(5%, 5%, 5%); }-}</style><g class="chart"><g class="edges"><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 261.71,-107.24 C 234.9900,-119.71 198.5900,-136.69 173.91,-148.21 L 173.62,-148.34"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 142.14,-252.3000 C 134.45,-263.07 124.6,-276.87 116.9000,-287.64 L 116.72,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 185.57,-252.12 C 205.09,-262.8900 230.21,-276.73 249.85,-287.56 L 250.31,-287.81"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 376.48,-180.1600 C 375.6900,-199.21 372.0100,-230.15 357.5,-252.0000 C 347.61,-266.8900 331.99,-278.84 317.47,-287.6 L 317.13,-287.8000"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 465.63,-36.124 C 446.95,-47.208 422.75,-61.5610 404.29,-72.516 L 403.8500,-72.774"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 376.5,-108.3 C 376.5,-119.07 376.5,-132.87 376.5,-143.64 L 376.5,-143.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 349.23,-104.13 C 345.98,-105.5100 342.69,-106.8400 339.5,-108.0000 C 308.87,-119.16 219.46,-142.43 173.89,-154.07 L 173.62,-154.13"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 196.94,-108.3 C 186.63,-119.07 173.43,-132.87 163.11,-143.64 L 162.87,-143.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 376.5,-36.303 C 376.5,-47.069 376.5,-60.866 376.5,-71.642 L 376.5,-71.896"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 230.79,-180.12 C 215.26,-190.8900 195.29,-204.7300 179.67,-215.56 L 179.3000,-215.81"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 261.93,-180.3000 C 265.93,-191.07 271.05,-204.8700 275.05,-215.64 L 275.15,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 281.5,-252.3000 C 281.5,-263.07 281.5,-276.87 281.5,-287.64 L 281.5,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 140.48,-108.3 C 141.71,-119.07 143.2800,-132.87 144.52,-143.64 L 144.55,-143.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 131.67,-33.503 C 134.99,-34.3890 138.29,-35.2310 141.5,-36.0 C 228.49,-56.813 254.19,-45.118 339.5,-72.0 C 342.64,-72.988 345.85,-74.178 349.02,-75.464 L 349.32,-75.589"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 85.48,-36.185 C 87.094,-54.712 91.3430,-84.678 102.5,-108.0000 C 108.8,-121.1700 119.1,-133.83 128.14,-143.4700 L 128.57,-143.93"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 292.65,-36.124 C 309.72,-46.887 331.67,-60.732 348.84,-71.555 L 349.24,-71.81"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 148.48,-180.3000 C 149.71,-191.07 151.28,-204.8700 152.52,-215.64 L 152.55,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 123.76,-180.3000 C 109.61,-191.07 91.476,-204.8700 77.314,-215.64 L 76.98,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 55.1,-107.24 C 74.311,-118.5400 99.821,-133.54 119.01,-144.83 L 119.46,-145.09"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 66.86,-252.3000 C 74.549,-263.07 84.404,-276.87 92.101,-287.64 L 92.283,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 220.02,-32.535 C 223.22,-33.729 226.41,-34.9 229.5,-36.0 C 277.9500,-53.2750 291.61,-53.2310 339.5,-72.0 C 342.56,-73.199 345.73,-74.524 348.87,-75.889 L 349.17,-76.021"/></g><g fill="rgb(0%, 0%, 0%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.0" stroke-opacity="1.0"><path d="M 555.07,-36.0340 C 507.09,-50.2640 440.79,-69.93 403.97,-80.854 L 403.53,-80.982"/></g></g><g class="shapes"><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="71.99992" width="65.00016" y="-324.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="262.00012" width="68.99976000000004" y="-108.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="112.9992" width="83.0016" y="-252.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="344.49996" width="64.00008000000003" y="-180.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="460.50016000000005" width="67.99968000000001" y="-36.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="349.5" width="54.0" y="-108.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="183.50012" width="59.99975999999998" y="-108.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="310.5012" width="131.99760000000003" y="-36.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="225.50012" width="59.99976000000001" y="-180.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="233.5012" width="95.9976" y="-324.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="214.5004" width="133.99919999999997" y="-252.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="111.5" width="54.0" y="-108.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="37.4984" width="94.00319999999999" y="-36.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="238.5" width="54.0" y="-36.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="119.5" width="54.0" y="-180.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="-3.999999999848569e-5" width="55.00008" y="-108.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="14.500399999999999" width="79.9992" y="-252.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="151.00012" width="68.99975999999998" y="-36.0" height="36.0"/></g><g fill="rgb(2%, 73%, 80%)" stroke="rgb(-51%, 30%, 37%)" stroke-width="1.0" fill-opacity="0.2" stroke-opacity="1.0"><rect x="547.0016" width="130.9967999999999" y="-36.0" height="36.0"/></g></g><g class="labels"><g fill="rgb(-51%, 30%, 37%)" stroke="none" stroke-width="0.0" font-size="14.0" fill-opacity="1.0" text-anchor="middle"><text x="104.5" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Additive">Additive</a></text><text x="296.5" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Direction">Direction</a></text><text x="154.5" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Distributive.html#t:Distributive">Distributive</a></text><text x="376.5" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Divisive">Divisive</a></text><text x="494.50000000000006" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:ExpField">ExpField</a></text><text x="376.5" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:Field">Field</a></text><text x="213.5" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Integral.html#t:Integral">Integral</a></text><text x="376.5" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:LowerBoundedField">LowerBoundedField</a></text><text x="255.5" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Module.html#t:Module">Module</a></text><text x="281.5" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Multiplicative">Multiplicative</a></text><text x="281.5" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Module.html#t:MultiplicativeAction">MultiplicativeAction</a></text><text x="138.5" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Norm">Norm</a></text><text x="84.5" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:QuotientField">QuotientField</a></text><text x="265.5" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Rational.html#t:Ratio">Ratio</a></text><text x="146.5" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Ring.html#t:Ring">Ring</a></text><text x="27.5" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Signed">Signed</a></text><text x="54.5" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Subtractive">Subtractive</a></text><text x="185.5" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:TrigField">TrigField</a></text><text x="612.5" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:UpperBoundedField">UpperBoundedField</a></text></g></g></g><g class="hud"></g></svg>+}</style><g class="chart"><g class="edges"><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 226.67,-180.3000 C 218.42,-189.6300 208.1400,-201.23 199.34,-211.1700 L 195.15,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 170.21,-180.3000 C 171.85,-189.1200 173.87,-199.97 175.64,-209.5300 L 176.82,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 110.74,-180.3000 C 123.2400,-189.81 138.84,-201.6800 152.07,-211.7500 L 157.2,-215.65"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 192.3600,-252.3000 C 198.9,-261.46 207.0,-272.81 214.02,-282.62 L 217.78,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 162.7,-252.3000 C 153.29,-261.7100 141.56,-273.44 131.56,-283.4400 L 127.1,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 76.124,-252.3000 C 82.0090,-261.46 89.304,-272.81 95.6150,-282.62 L 99.004,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 181.36,-36.303 C 176.31,-45.3740 170.05,-56.5960 164.62,-66.35 L 161.53,-71.896"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 124.56,-96.119 C 98.982,-102.5 62.272,-116.1700 45.0,-144.0 C 32.513,-164.12 41.437,-191.1 51.02,-210.0600 L 53.992,-215.6700"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 179.35,-101.76 C 205.58,-112.2 246.22,-128.66 281.0,-144.0 C 281.87,-144.38 282.75,-144.78 283.64,-145.17 L 289.5500,-147.86"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 338.83,-108.3 C 335.11,-117.29 330.51,-128.39 326.5,-138.08 L 324.09,-143.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 254.03,-36.4830 C 232.89,-47.366 205.83,-61.292 184.89,-72.069 L 179.16,-75.02"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 291.56,-36.4120 C 296.76,-61.887 306.46,-109.37 312.26,-137.79 L 313.51,-143.89"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 122.6400,-36.303 C 127.6900,-45.3740 133.95,-56.5960 139.38,-66.35 L 142.47,-71.896"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 289.61,-177.0 C 269.5900,-187.22 242.1500,-201.2400 219.7400,-212.7 L 214.1500,-215.55"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 313.79,-180.3000 C 312.15,-189.1200 310.13,-199.97 308.36,-209.5300 L 307.18,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 285.71,-252.3000 C 275.84,-261.6400 263.55,-273.26 253.03,-283.21 L 248.34,-287.65"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 63.4720,-36.4830 C 80.423,-46.539 101.75,-59.193 119.2300,-69.561 L 124.5200,-72.699"/></g></g><g class="shapes"><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="58.9997" x="212.5002" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="64.0001" x="198.0000" y="-324.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="140.0" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="67.9997" x="54.0002" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="81.0" x="139.5" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="61.9999" x="34.0000" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="66.0002" x="157.9999" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="125.0" y="-108.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="58.9997" x="316.5002" y="-108.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="94.0032" x="62.9984" y="-324.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="92.0016" x="241.9992" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="86.0" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="290.0" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="77.9976" x="265.0012" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="67.9997" x="0.0002" y="-36.0"/></g></g><g class="labels"><g fill="rgb(33%, -22%, 26%)" fill-opacity="1.0" font-size="14.0" stroke="none" stroke-width="0.0" text-anchor="middle"><text x="242.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Action.html#t:AdditiveAction">Actions</a></text><text x="230.0" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Additive">Additive</a></text><text x="167.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Basis">Basis</a></text><text x="88.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Direction">Direction</a></text><text x="180.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Distributive.html#t:Distributive">Distributive</a></text><text x="65.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Divisive">Divisive</a></text><text x="191.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:ExpField">ExpField</a></text><text x="152.0" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:Field">Field</a></text><text x="346.0" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Integral.html#t:Integral">Integral</a></text><text x="110.0" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Multiplicative">Multiplicative</a></text><text x="288.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:QuotientField">QuotientField</a></text><text x="113.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Rational.html#t:Ratio">Ratio</a></text><text x="317.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Ring.html#t:Ring">Ring</a></text><text x="304.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Subtractive">Subtractive</a></text><text x="34.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:TrigField">TrigField</a></text></g></g></g><g class="hud"/></svg>
src/NumHask.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE RebindableSyntax #-}-{-# OPTIONS_GHC -Wall #-} {-# OPTIONS_HADDOCK prune #-} -- | Numeric classes.@@ -57,38 +56,47 @@ BoundedJoinSemiLattice (..), BoundedMeetSemiLattice (..), - -- * Module+ -- * Action AdditiveAction (..),- (+.),+ (+|), SubtractiveAction (..),- (-.),+ (-|), MultiplicativeAction (..),- (*.),+ (*|), DivisiveAction (..),- (/.),+ (/|), Module, -- * Metric- Signed (..),- Norm (..),+ Basis (..),+ Absolute,+ Sign,+ EndoBased,+ abs,+ signum, distance, Direction (..), Polar (..), polar, coord, Epsilon (..),+ aboutEqual,+ nearZero, (~=), -- * Complex Complex (..),+ (+:), realPart, imagPart, -- * Integral Integral (..), ToIntegral (..),+ ToInt, FromIntegral (..), FromInteger (..),+ FromInt, even, odd, (^^),@@ -109,6 +117,17 @@ ) where +import NumHask.Algebra.Action+ ( AdditiveAction (..),+ DivisiveAction (..),+ Module,+ MultiplicativeAction (..),+ SubtractiveAction (..),+ (*|),+ (+|),+ (-|),+ (/|),+ ) import NumHask.Algebra.Additive ( Additive (..), Subtractive (..),@@ -136,29 +155,22 @@ (<\), ) import NumHask.Algebra.Metric- ( Direction (..),+ ( Absolute,+ Basis (..),+ Direction (..),+ EndoBased, Epsilon (..),- Norm (..), Polar (..),- Signed (..),+ Sign, aboutEqual,+ abs, coord, distance, nearZero, polar,+ signum, (~=), )-import NumHask.Algebra.Module- ( AdditiveAction (..),- DivisiveAction (..),- Module,- MultiplicativeAction (..),- SubtractiveAction (..),- (*.),- (+.),- (-.),- (/.),- ) import NumHask.Algebra.Multiplicative ( Divisive (..), Multiplicative (..),@@ -173,11 +185,13 @@ StarSemiring (..), two, )-import NumHask.Data.Complex (Complex (..), imagPart, realPart)+import NumHask.Data.Complex (Complex (..), imagPart, realPart, (+:)) import NumHask.Data.Integral- ( FromInteger (..),+ ( FromInt,+ FromInteger (..), FromIntegral (..), Integral (..),+ ToInt, ToIntegral (..), even, odd,@@ -252,19 +266,16 @@ -- numhask is largely a set of classes that can replace the 'GHC.Num.Num' class and it's descendents. -- 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.+-- - __/balanced class density/__. The numeric heirarchy begins with addition and multiplication rather than from a Monoidal or 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--- representing major teleological fault lines.+-- - __/operator-first/__. In all cases, a class exists to define useful operators.+-- Major class groupings, such as 'Distributive', 'Ring' and 'Field' are type synonyms. ----- - __/lawful/__. Most classes have laws associated with them that serve to relate class operators--- together in a meaningful way.+-- - __/lawful/__. All classes have laws associated with them that serve to relate class operators together in a meaningful way. -- -- - __/low-impact/__. The library attempts to fit in with the rest of the Haskell ecosystem. -- It provides instances for common numbers: 'GHC.Num.Int', 'GHC.Num.Integer', 'GHC.Float.Double',--- 'GHC.Float.Float' and the Word classes. It avoids name (or idea) clashes with other popular libraries+-- 'GHC.Float.Float', 'GHC.Natural.Natural', and the Word classes. It avoids name (or idea) clashes with other popular libraries -- and adopts conventions in the <https://hackage.haskell.org/package/base/docs/Prelude.html current prelude> -- where they make sense. --@@ -274,6 +285,7 @@ -- $pictures -- -- The class heirarchy looks somewhat like this:+-- --  -- $mapping@@ -310,14 +322,16 @@ -- > -- or @1@ (positive). -- > signum :: a -> a ----- 'abs' is a function in the 'NumHask.Algebra.Metric.Signed' class.--- The concept of an absolute value can also include situations where the domain and codomain--- are different, and 'norm' as a function in the 'NumHask.Algebra.Metric.Norm' class is supplied--- for these cases.+-- The concept of an absolute value and the sign of a number can include situations where the domain type is different to the absolute and sign codomain types. ----- 'NumHask.Algebra.Metric.sign' replaces 'GHC.Num.signum', because signum is simply a naming crime.--- 'NumHask.Algebra.Metric.basis' can also be seen as a generalisation of sign.+-- A new class, 'Basis' is supplied to handle these situations: --+-- - the 'magnitude' method is a generalisation of 'abs'+--+-- - the 'basis' method is a generalisation of 'signum'+--+-- 'NumHask.Algebra.Metric.abs' and 'NumHask.Algebra.Metric.signum' are specialisations of these methods.+-- -- > -- | Conversion from an 'Integer'. -- > -- An integer literal represents the application of the function -- > -- 'fromInteger' to the appropriate value of type 'Integer',@@ -326,14 +340,18 @@ -- -- 'FromInteger' becomes its own class and 'FromIntegral' is introduced to polymorphise the covariant. ----- Mappings from other areas of prelude include:\+-- Mappings from other areas of prelude include: ----- 'GHC.Real.Integral' becomes 'Integral' and a polymorphic 'ToIntegral' is introduced.+-- - 'GHC.Real.Integral' becomes 'Integral' and a polymorphic 'ToIntegral' is introduced. ----- 'GHC.Real.Fractional' is roughly synonymous to 'Field' together with a polymorphic 'FromRatio'.+-- - 'GHC.Real.Fractional' is roughly synonymous to 'Field' together with a polymorphic 'FromRatio'. ----- 'GHC.Real.RealFrac' becomes the polymorphic 'QuotientField'+-- - 'GHC.Real.RealFrac' becomes 'QuotientField' with a polymorphic 'Whole' type using Type Families. ----- 'GHC.Float.Floating' is split into 'ExpField' and 'TrigField'+-- - 'GHC.Float.Floating' is split into 'ExpField' and 'TrigField' ----- 'GHC.Float.RealFloat' is not attempted. Life is too short.+-- - 'GHC.Float.RealFloat' is not attempted. Life is too short.+--+-- - Complex is resupplied in 'NumHask.Data.Complex' but with some functionality deriving via 'NumHask.Algebra.Metric.EuclideanPair'. The underlying representation has also been switched to a newtype-wrapped tuple.+--+-- In addition to base changes, alternatives to 'sum' and 'product' from 'Data.Foldable' are also supplied.
+ src/NumHask/Algebra/Action.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE TypeFamilies #-}++-- | Algebra for Actions+--+-- Convention: the |'s in the operators point towards the higher-kinded number, representing an operator or action __into__ a structure.+module NumHask.Algebra.Action+ ( AdditiveAction (..),+ (+|),+ SubtractiveAction (..),+ (-|),+ MultiplicativeAction (..),+ (*|),+ DivisiveAction (..),+ (/|),+ Module,+ )+where++import Data.Kind (Type)+import NumHask.Algebra.Additive (Additive, Subtractive, negate)+import NumHask.Algebra.Multiplicative (Divisive, Multiplicative, recip)+import NumHask.Algebra.Ring (Distributive)+import Prelude (flip)++-- | Additive Action+--+-- > m |+ zero == m+class+ (Additive (AdditiveScalar m)) =>+ AdditiveAction m+ where+ type AdditiveScalar m :: Type++ infixl 6 |++ (|+) :: m -> AdditiveScalar m -> m++infixl 6 +|++-- | flipped additive action+--+-- > (+|) == flip (|+)+-- > zero +| m = m+(+|) :: (AdditiveAction m) => AdditiveScalar m -> m -> m+(+|) = flip (|+)++-- | Subtractive Action+--+-- > m |- zero = m+class+ (AdditiveAction m, Subtractive (AdditiveScalar m)) =>+ SubtractiveAction m+ where+ infixl 6 |-+ (|-) :: m -> AdditiveScalar m -> m++infixl 6 -|++-- | Subtraction with the scalar on the left+--+-- > (-|) == (+|) . negate+-- > zero -| m = negate m+(-|) :: (AdditiveAction m, Subtractive m) => AdditiveScalar m -> m -> m+a -| b = a +| negate b++-- | Multiplicative Action+--+-- > m |* one = m+-- > m |* zero = zero+class+ (Multiplicative (Scalar m)) =>+ MultiplicativeAction m+ where+ type Scalar m :: Type++ infixl 7 |*+ (|*) :: m -> Scalar m -> m++infixl 7 *|++-- | flipped multiplicative action+--+-- > (*|) == flip (|*)+-- > one *| m = one+-- > zero *| m = zero+(*|) :: (MultiplicativeAction m) => Scalar m -> m -> m+(*|) = flip (|*)++-- | Divisive Action+--+-- > m |/ one = m+class+ (Divisive (Scalar m), MultiplicativeAction m) =>+ DivisiveAction m+ where+ infixl 7 |/+ (|/) :: m -> Scalar m -> m++-- | left scalar division+--+-- > (/|) == (*|) . recip+-- > one |/ m = recip m+(/|) :: (MultiplicativeAction m, Divisive m) => Scalar m -> m -> m+a /| b = a *| recip b++-- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module>+--+-- > a *| one == a+-- > (a + b) *| c == (a *| c) + (b *| c)+-- > c |* (a + b) == (c |* a) + (c |* b)+-- > a *| zero == zero+-- > a *| b == b |* a+type Module m = (Distributive (Scalar m), MultiplicativeAction m)
src/NumHask/Algebra/Additive.hs view
@@ -1,6 +1,3 @@-{-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_GHC -Wno-unused-imports #-}- -- | Additive classes module NumHask.Algebra.Additive ( Additive (..),@@ -10,13 +7,12 @@ ) where -import Control.Applicative import Data.Foldable (foldl') import Data.Int (Int16, Int32, Int64, Int8) import Data.Traversable (mapAccumL) import Data.Word (Word, Word16, Word32, Word64, Word8) import GHC.Natural (Natural (..))-import Prelude (Applicative, Bool, Double, Float, Functor, Int, Integer, fromInteger, ($))+import Prelude (Bool, Double, Float, Int, Integer, fromInteger) import qualified Prelude as P -- $setup@@ -74,6 +70,8 @@ -- >>> 1 - 2 -- -1 class (Additive a) => Subtractive a where+ {-# MINIMAL (-) | negate #-}+ negate :: a -> a negate a = zero - a
src/NumHask/Algebra/Field.hs view
@@ -1,10 +1,5 @@ {-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE TypeFamilies #-} -- | Field classes module NumHask.Algebra.Field@@ -20,13 +15,14 @@ where import Data.Bool (bool)+import Data.Kind import NumHask.Algebra.Additive (Additive (..), Subtractive (..), (-)) import NumHask.Algebra.Multiplicative ( Divisive (..), Multiplicative (..), (/), )-import NumHask.Algebra.Ring (Distributive, two)+import NumHask.Algebra.Ring (Distributive, Ring, two) import NumHask.Data.Integral (Integral, even) import Prelude ((.)) import qualified Prelude as P@@ -61,15 +57,7 @@ -- > recip a == one / a || a == zero -- > recip a * a == one || a == zero -- > a * recip a == one || a == zero-class- (Distributive a, Subtractive a, Divisive a) =>- Field a--instance Field P.Double--instance Field P.Float--instance (Field b) => Field (a -> b)+type Field a = (Ring a, Divisive a) -- | A hyperbolic field class --@@ -113,31 +101,30 @@ exp f = exp . f log f = log . f --- | Conversion from a 'Field' to a 'NumHask.Algebra.Ring'+-- | Quotienting of a 'Field' into a 'NumHask.Algebra.Ring' -- -- See [Field of fractions](https://en.wikipedia.org/wiki/Field_of_fractions) -- -- > \a -> a - one < floor a <= a <= ceiling a < a + one--- prop> (\a -> a - one < fromIntegral (floor a :: Int) && fromIntegral (floor a :: Int) <= a && a <= fromIntegral (ceiling a :: Int) && fromIntegral (ceiling a :: Int) <= a + one) :: Double -> Bool--- prop> \a -> (round a :: Int) ~= (floor (a + half) :: Int)-class (Field a, Multiplicative b, Additive b) => QuotientField a b where- properFraction :: a -> (b, a)+class (Field a) => QuotientField a where+ type Whole a :: Type+ properFraction :: a -> (Whole a, a) - -- | round to the nearest integral+ -- | round to the nearest Int -- -- Exact ties are managed by rounding down ties if the whole component is even. --- -- >>> round (1.5 :: Double) :: Int+ -- >>> round (1.5 :: Double) -- 2 --- -- >>> round (2.5 :: Double) :: Int+ -- >>> round (2.5 :: Double) -- 2- round :: a -> b- default round :: (P.Ord a, P.Ord b, Subtractive b, Integral b) => a -> b+ round :: (P.Eq (Whole a), Ring (Whole a)) => a -> Whole a+ default round :: (Integral (Whole a), P.Eq (Whole a), P.Ord a, Ring (Whole a)) => a -> Whole a 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))+ half_down = abs' r - half abs' a | a P.< zero = negate a | P.otherwise = a@@ -148,55 +135,42 @@ -- | supply the next upper whole component --- -- >>> ceiling (1.001 :: Double) :: Int+ -- >>> ceiling (1.001 :: Double) -- 2- ceiling :: a -> b- default ceiling :: (P.Ord a) => a -> b+ ceiling :: (Distributive (Whole a)) => a -> Whole a+ default ceiling :: (P.Ord a, Distributive (Whole a)) => a -> Whole a ceiling x = bool n (n + one) (r P.>= zero) where (n, r) = properFraction x -- | supply the previous lower whole component --- -- >>> floor (1.001 :: Double) :: Int+ -- >>> floor (1.001 :: Double) -- 1- floor :: a -> b- default floor :: (P.Ord a, Subtractive b) => a -> b+ floor :: (Ring (Whole a)) => a -> Whole a+ default floor :: (P.Ord a, Ring (Whole a)) => a -> Whole a floor x = bool n (n - one) (r P.< zero) where (n, r) = properFraction x -- | supply the whole component closest to zero --- -- >>> floor (-1.001 :: Double) :: Int+ -- >>> floor (-1.001 :: Double) -- -2 --- -- >>> truncate (-1.001 :: Double) :: Int+ -- >>> truncate (-1.001 :: Double) -- -1- truncate :: a -> b- default truncate :: (P.Ord a) => a -> b+ truncate :: (Ring (Whole a)) => a -> Whole a+ default truncate :: (P.Ord a, Ring (Whole a)) => a -> Whole a truncate x = bool (ceiling x) (floor x) (x P.> zero) -instance QuotientField P.Float P.Integer where- properFraction = P.properFraction--instance QuotientField P.Double P.Integer where- properFraction = P.properFraction--instance QuotientField P.Float P.Int where+instance QuotientField P.Float where+ type Whole P.Float = P.Int properFraction = P.properFraction -instance QuotientField P.Double P.Int where+instance QuotientField P.Double where+ type Whole P.Double = P.Int properFraction = P.properFraction--instance (QuotientField b c) => QuotientField (a -> b) (a -> c) where- properFraction f = (P.fst . frac, P.snd . frac)- where- frac a = properFraction @b @c (f a)- round f = round . f- ceiling f = ceiling . f- floor f = floor . f- truncate f = truncate . f -- | infinity is defined for any 'Field'. --
src/NumHask/Algebra/Group.hs view
@@ -1,7 +1,3 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}- -- | The Group hierarchy module NumHask.Algebra.Group ( Magma (..),@@ -94,9 +90,7 @@ -- | 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+type Group a = (Associative a, Unital a, Invertible a) -- | An Absorbing is a Magma with an -- <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element>@@ -125,6 +119,4 @@ -- | An <https://en.wikipedia.org/wiki/Abelian_group Abelian Group> is an -- 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+type AbelianGroup a = (Associative a, Unital a, Invertible a, Commutative a)
src/NumHask/Algebra/Lattice.hs view
@@ -1,10 +1,3 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_GHC -Wno-redundant-constraints #-}- -- | [Lattices](https://en.wikipedia.org/wiki/Lattice_(order\)) module NumHask.Algebra.Lattice ( JoinSemiLattice (..),@@ -15,12 +8,13 @@ (</), BoundedJoinSemiLattice (..), BoundedMeetSemiLattice (..),+ Lattice,+ BoundedLattice, ) where import Data.Bool (Bool (..), (&&), (||)) import Data.Eq (Eq ((==)))-import Data.Function (const) import Data.Int (Int16, Int32, Int64, Int8) import Data.Ord (Ord (..)) import Data.Word (Word16, Word32, Word64, Word8)@@ -78,9 +72,7 @@ -- see [Absorption Law](http://en.wikipedia.org/wiki/Absorption_law) and [Lattice](http://en.wikipedia.org/wiki/Lattice_(order\)) -- -- > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a-class (JoinSemiLattice a, MeetSemiLattice a) => Lattice a--instance (JoinSemiLattice a, MeetSemiLattice a) => Lattice a+type Lattice a = (JoinSemiLattice a, MeetSemiLattice a) -- | A join-semilattice with an identity element 'bottom' for '\/'. --@@ -95,9 +87,7 @@ 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+type BoundedLattice a = (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) instance JoinSemiLattice Float where (\/) = min@@ -189,14 +179,6 @@ instance MeetSemiLattice Word64 where (/\) = max -instance (Eq (a -> b), JoinSemiLattice b) => JoinSemiLattice (a -> b) where- f \/ f' = \a -> f a \/ f' a--instance (Eq (a -> b), MeetSemiLattice b) => MeetSemiLattice (a -> b) where- f /\ f' = \a -> f a /\ f' a---- from here- instance BoundedJoinSemiLattice Float where bottom = negInfinity @@ -277,9 +259,3 @@ instance BoundedMeetSemiLattice Word64 where top = maxBound--instance (Eq (a -> b), BoundedJoinSemiLattice b) => BoundedJoinSemiLattice (a -> b) where- bottom = const bottom--instance (Eq (a -> b), BoundedMeetSemiLattice b) => BoundedMeetSemiLattice (a -> b) where- top = const top
src/NumHask/Algebra/Metric.hs view
@@ -1,39 +1,45 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# OPTIONS_GHC -Wno-type-equality-out-of-scope #-} -- | Metric classes module NumHask.Algebra.Metric- ( Signed (..),- Norm (..),+ ( Basis (..),+ Absolute,+ Sign,+ EndoBased,+ abs,+ signum, distance, Direction (..), Polar (..), polar, coord, Epsilon (..),+ nearZero,+ aboutEqual, (~=),+ EuclideanPair (..), ) where -import Data.Bool (bool)+import Control.Applicative+import Data.Bool import Data.Int (Int16, Int32, Int64, Int8)+import Data.Kind import Data.Word (Word16, Word32, Word64, Word8)-import GHC.Generics (Generic)+import GHC.Generics import GHC.Natural (Natural (..))-import NumHask.Algebra.Additive (Additive (zero), Subtractive (..), (-))-import NumHask.Algebra.Module (MultiplicativeAction ((.*)))-import NumHask.Algebra.Multiplicative (Multiplicative (one))-import Prelude hiding- ( Bounded (..),- Integral (..),- negate,- (*),- (-),- )+import NumHask.Algebra.Action+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import Prelude (Double, Eq (..), Float, Functor (..), Int, Integer, Ord, Show, Word, fromRational) import qualified Prelude as P -- $setup@@ -41,224 +47,183 @@ -- >>> :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.------ prop> \a -> abs a * sign a ~= a+-- | 'Basis' encapsulates the notion of magnitude (intuitively the quotienting of a higher-kinded number to a scalar one) and the basis on which the magnitude quotienting was performed. An instance needs to satisfy these laws: ----- abs zero == zero, so any value for sign zero is ok. We choose lawful neutral:+-- > \a -> magnitude a >= zero+-- > \a -> magnitude zero == zero+-- > \a -> a == magnitude a *| basis a+-- > \a -> magnitude (basis a) == one ----- >>> sign zero == zero--- True+-- The names chosen are meant to represent the spiritual idea of a basis rather than a specific mathematics. See https://en.wikipedia.org/wiki/Basis_(linear_algebra) & https://en.wikipedia.org/wiki/Norm_(mathematics) for some mathematical motivations. ----- >>> abs (-1)--- 1+-- >>> magnitude (-0.5 :: Double)+-- 0.5 ----- >>> sign (-1)--- -1-class- (Additive a, Multiplicative a) =>- Signed a- where- sign :: a -> a- abs :: a -> a--instance Signed Double where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Float where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Int where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Integer where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Natural where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = id--instance Signed Int8 where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Int16 where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Int32 where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs--instance Signed Int64 where- sign a =- case compare a zero of- EQ -> zero- GT -> one- LT -> negate one- abs = P.abs+-- >>> basis (-0.5 :: Double)+-- -1.0+class (Distributive (Mag a)) => Basis a where+ type Mag a :: Type+ type Base a :: Type -instance Signed Word where- sign a = bool one zero (a == zero)- abs = P.abs+ -- | or length, or ||v||+ magnitude :: a -> Mag a -instance Signed Word8 where- sign a = bool one zero (a == zero)- abs = P.abs+ -- | or direction, or v-hat+ basis :: a -> Base a -instance Signed Word16 where- sign a = bool one zero (a == zero)- abs = P.abs+-- | Basis where the domain and magnitude codomain are the same.+type Absolute a = (Basis a, Mag a ~ a) -instance Signed Word32 where- sign a = bool one zero (a == zero)- abs = P.abs+-- | Basis where the domain and basis codomain are the same.+type Sign a = (Basis a, Base a ~ a) -instance Signed Word64 where- sign a = bool one zero (a == zero)- abs = P.abs+-- | Basis where the domain, magnitude codomain and basis codomain are the same.+type EndoBased a = (Basis a, Mag a ~ a, Base a ~ a) --- | Norm is a slight generalisation of Signed. The class has the same shape but allows the codomain to be different to the domain.+-- | The absolute value of a number. ----- > \a -> norm a >= zero--- > \a -> norm zero == zero--- > \a -> a == norm a .* basis a--- > \a -> norm (basis a) == one+-- prop> \a -> abs a * signum a ~= a ----- >>> norm (-0.5 :: Double) :: Double--- 0.5 ----- >>> basis (-0.5 :: Double) :: Double--- -1.0-class (Additive a, Multiplicative b, Additive b) => Norm a b | a -> b where- -- | or length, or ||v||- norm :: a -> b+-- >>> abs (-1)+-- 1+abs :: (Absolute a) => a -> a+abs = magnitude - -- | or direction, or v-hat- basis :: a -> a+-- | The sign of a number.+--+-- >>> signum (-1)+-- -1+--+-- @abs zero == zero@, so any value for @signum zero@ is ok. We choose lawful neutral:+--+-- >>> signum zero == zero+-- True+signum :: (Sign a) => a -> a+signum = basis -instance Norm Double Double where- norm = P.abs+instance Basis Double where+ type Mag Double = Double+ type Base Double = Double+ magnitude = P.abs basis = P.signum -instance Norm Float Float where- norm = P.abs+instance Basis Float where+ type Mag Float = Float+ type Base Float = Float+ magnitude = P.abs basis = P.signum -instance Norm Int Int where- norm = P.abs+instance Basis Int where+ type Mag Int = Int+ type Base Int = Int+ magnitude = P.abs basis = P.signum -instance Norm Integer Integer where- norm = P.abs+instance Basis Integer where+ type Mag Integer = Integer+ type Base Integer = Integer+ magnitude = P.abs basis = P.signum -instance Norm Natural Natural where- norm = P.abs+instance Basis Natural where+ type Mag Natural = Natural+ type Base Natural = Natural+ magnitude = P.abs basis = P.signum -instance Norm Int8 Int8 where- norm = P.abs+instance Basis Int8 where+ type Mag Int8 = Int8+ type Base Int8 = Int8+ magnitude = P.abs basis = P.signum -instance Norm Int16 Int16 where- norm = P.abs+instance Basis Int16 where+ type Mag Int16 = Int16+ type Base Int16 = Int16+ magnitude = P.abs basis = P.signum -instance Norm Int32 Int32 where- norm = P.abs+instance Basis Int32 where+ type Mag Int32 = Int32+ type Base Int32 = Int32+ magnitude = P.abs basis = P.signum -instance Norm Int64 Int64 where- norm = P.abs+instance Basis Int64 where+ type Mag Int64 = Int64+ type Base Int64 = Int64+ magnitude = P.abs basis = P.signum -instance Norm Word Word where- norm = P.abs+instance Basis Word where+ type Mag Word = Word+ type Base Word = Word+ magnitude = P.abs basis = P.signum -instance Norm Word8 Word8 where- norm = P.abs+instance Basis Word8 where+ type Mag Word8 = Word8+ type Base Word8 = Word8+ magnitude = P.abs basis = P.signum -instance Norm Word16 Word16 where- norm = P.abs+instance Basis Word16 where+ type Mag Word16 = Word16+ type Base Word16 = Word16+ magnitude = P.abs basis = P.signum -instance Norm Word32 Word32 where- norm = P.abs+instance Basis Word32 where+ type Mag Word32 = Word32+ type Base Word32 = Word32+ magnitude = P.abs basis = P.signum -instance Norm Word64 Word64 where- norm = P.abs+instance Basis Word64 where+ type Mag Word64 = Word64+ type Base Word64 = Word64+ magnitude = P.abs basis = P.signum --- | Distance, which combines the Subtractive notion of difference, with Norm.+-- | Distance, which combines the Subtractive notion of difference, with Basis. -- -- > distance a b >= zero -- > distance a a == zero--- > distance a b .* basis (a - b) == a - b-distance :: (Norm a b, Subtractive a) => a -> a -> b-distance a b = norm (a - b)+-- > distance a b *| basis (a - b) == a - b+distance :: (Basis a, Subtractive a) => a -> a -> Mag a+distance a b = magnitude (a - b) --- | Convert between a "co-ordinated" or "higher-kinded" number and representations of an angle. Typically thought of as polar co-ordinate conversion.+-- | Convert between a "co-ordinated" or "higher-kinded" number and a direction. ----- See [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system) -- -- > ray . angle == basis--- > norm (ray x) == one-class (Additive coord, Multiplicative coord, Additive dir, Multiplicative dir) => Direction coord dir | coord -> dir where- angle :: coord -> dir- ray :: dir -> coord+-- > magnitude (ray x) == one+class (Distributive coord, Distributive (Dir coord)) => Direction coord where+ type Dir coord :: Type+ angle :: coord -> Dir coord+ ray :: Dir coord -> coord --- | Something that has a magnitude and a direction.-data Polar mag dir = Polar {magnitude :: !mag, direction :: !dir}- deriving (Eq, Show, Generic)+-- | Something that has a magnitude and a direction, with both expressed as the same type.+--+-- See [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system)+data Polar a = Polar {radial :: a, azimuth :: a}+ deriving (Generic, Show, Eq) --- | Convert from a number to a Polar.-polar :: (Norm coord mag, Direction coord dir) => coord -> Polar mag dir-polar z = Polar (norm z) (angle z)+instance (Additive a, Multiplicative a) => Basis (Polar a) where+ type Mag (Polar a) = a+ type Base (Polar a) = a+ magnitude = radial+ basis = azimuth --- | Convert from a Polar to a (coordinated aka higher-kinded) number.-coord :: (MultiplicativeAction coord mag, Direction coord dir) => Polar mag dir -> coord-coord (Polar m d) = m .* ray d+-- | Convert a higher-kinded number that has direction, to a 'Polar'+polar :: (Dir (Base a) ~ Mag a, Basis a, Direction (Base a)) => a -> Polar (Mag a)+polar x = Polar (magnitude x) (angle (basis x)) +-- | Convert a Polar to a (higher-kinded) number that has a direction.+coord :: (Scalar m ~ Dir m, MultiplicativeAction m, Direction m) => Polar (Scalar m) -> m+coord x = radial x *| ray (azimuth x)+ -- | A small number, especially useful for approximate equality. class (Eq a, Additive a) =>@@ -267,21 +232,22 @@ epsilon :: a epsilon = zero - -- | are we near enough?- --- -- >>> nearZero (epsilon :: Double)- -- True- nearZero :: a -> Bool- default nearZero :: (Ord a, Subtractive a) => a -> Bool- nearZero a = epsilon >= a && epsilon >= negate a+-- | Note that the constraint is Lattice rather than Ord allowing broader usage.+--+-- >>> nearZero (epsilon :: Double)+-- True+--+-- >>> nearZero (epsilon :: EuclideanPair Double)+-- True+nearZero :: (Epsilon a, Lattice a, Subtractive a) => a -> Bool+nearZero a = epsilon /\ a == epsilon && epsilon /\ negate a == epsilon - -- | Approximate equality- --- -- >>> aboutEqual zero (epsilon :: Double)- -- True- aboutEqual :: a -> a -> Bool- default aboutEqual :: (Subtractive a) => a -> a -> Bool- aboutEqual a b = nearZero $ a - b+-- | Approximate equality+--+-- >>> aboutEqual zero (epsilon :: Double)+-- True+aboutEqual :: (Epsilon a, Lattice a, Subtractive a) => a -> a -> Bool+aboutEqual a b = nearZero (a - b) infixl 4 ~= @@ -289,7 +255,7 @@ -- -- >>> (1.0 + epsilon) ~= (1.0 :: Double) -- True-(~=) :: (Epsilon a) => a -> a -> Bool+(~=) :: (Epsilon a) => (Lattice a, Subtractive a) => a -> a -> Bool (~=) = aboutEqual -- | 1e-14@@ -322,3 +288,107 @@ instance Epsilon Word32 instance Epsilon Word64++-- | Two dimensional cartesian coordinates.+newtype EuclideanPair a = EuclideanPair {euclidPair :: (a, a)}+ deriving stock+ ( Generic,+ Eq,+ Show+ )++instance Functor EuclideanPair where+ fmap f (EuclideanPair (x, y)) = EuclideanPair (f x, f y)++instance Applicative EuclideanPair where+ pure x = EuclideanPair (x, x)+ EuclideanPair (fx, fy) <*> EuclideanPair (x, y) = EuclideanPair (fx x, fy y)+ liftA2 f (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (f x x', f y y')++instance (Additive a) => Additive (EuclideanPair a) where+ (+) = liftA2 (+)+ zero = pure zero++instance (Subtractive a) => Subtractive (EuclideanPair a) where+ negate = fmap negate++instance+ (Multiplicative a) =>+ Multiplicative (EuclideanPair a)+ where+ (*) = liftA2 (*)+ one = pure one++instance+ (Subtractive a, Divisive a) =>+ Divisive (EuclideanPair a)+ where+ recip = fmap recip++instance (TrigField a) => Direction (EuclideanPair a) where+ type Dir (EuclideanPair a) = a+ angle (EuclideanPair (x, y)) = atan2 y x+ ray x = EuclideanPair (cos x, sin x)++instance+ (ExpField a, Eq a) =>+ Basis (EuclideanPair a)+ where+ type Mag (EuclideanPair a) = a+ type Base (EuclideanPair a) = EuclideanPair a++ magnitude (EuclideanPair (x, y)) = sqrt (x * x + y * y)+ basis p = let m = magnitude p in bool (p |/ m) zero (m == zero)++instance+ (Epsilon a) =>+ Epsilon (EuclideanPair a)+ where+ epsilon = pure epsilon++instance (JoinSemiLattice a) => JoinSemiLattice (EuclideanPair a) where+ (\/) (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (x \/ x', y \/ y')++instance (MeetSemiLattice a) => MeetSemiLattice (EuclideanPair a) where+ (/\) (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (x /\ x', y /\ y')++instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (EuclideanPair a) where+ bottom = pure bottom++instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (EuclideanPair a) where+ top = pure top++instance (Multiplicative a) => MultiplicativeAction (EuclideanPair a) where+ type Scalar (EuclideanPair a) = a+ (|*) (EuclideanPair (x, y)) s = EuclideanPair (s * x, s * y)++instance (Divisive a) => DivisiveAction (EuclideanPair a) where+ (|/) e s = fmap (/ s) e++instance (Ord a, TrigField a, ExpField a) => ExpField (EuclideanPair a) where+ exp (EuclideanPair (x, y)) = EuclideanPair (exp x * cos y, exp x * sin y)+ log (EuclideanPair (x, y)) = EuclideanPair (log (sqrt (x * x + y * y)), atan2' y x)+ where+ atan2' y x+ | x P.> zero = atan (y / x)+ | x P.== zero P.&& y P.> zero = pi / (one + one)+ | x P.< one P.&& y P.> one = pi + atan (y / x)+ | (x P.<= zero P.&& y P.< zero) || (x P.< zero) =+ negate (atan2' (negate y) x)+ | y P.== zero = pi -- must be after the previous test on zero y+ | x P.== zero P.&& y P.== zero = y -- must be after the other double zero tests+ | P.otherwise = x + y -- x or y is a NaN, return a NaN (via +)++instance (Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (EuclideanPair a) where+ type Whole (EuclideanPair a) = EuclideanPair (Whole a)++ properFraction (EuclideanPair (x, y)) =+ (EuclideanPair (xwhole, ywhole), EuclideanPair (xfrac, yfrac))+ where+ (xwhole, xfrac) = properFraction x+ (ywhole, yfrac) = properFraction y++ round (EuclideanPair (x, y)) = EuclideanPair (round x, round y)+ ceiling (EuclideanPair (x, y)) = EuclideanPair (ceiling x, ceiling y)+ floor (EuclideanPair (x, y)) = EuclideanPair (floor x, floor y)+ truncate (EuclideanPair (x, y)) = EuclideanPair (truncate x, truncate y)
− src/NumHask/Algebra/Module.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE RebindableSyntax #-}-{-# OPTIONS_GHC -Wall #-}---- | Algebra for Modules-module NumHask.Algebra.Module- ( AdditiveAction (..),- (+.),- SubtractiveAction (..),- (-.),- MultiplicativeAction (..),- (*.),- DivisiveAction (..),- (/.),- Module,- )-where--import NumHask.Algebra.Additive (Additive, Subtractive, negate)-import NumHask.Algebra.Multiplicative (Divisive, Multiplicative, recip)-import NumHask.Algebra.Ring (Distributive)-import Prelude (flip)---- | Additive Action-class- (Additive a) =>- AdditiveAction m a- | m -> a- where- infixl 6 .+- (.+) :: a -> m -> m--infixl 6 +.---- | flipped additive action------ > (+.) == flip (.+)-(+.) :: (AdditiveAction m a) => m -> a -> m-(+.) = flip (.+)---- | Subtractive Action-class- (Subtractive a) =>- SubtractiveAction m a- | m -> a- where- infixl 6 .-- (.-) :: a -> m -> 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) =>- MultiplicativeAction m a- | m -> a- where- infixl 7 .*- (.*) :: a -> m -> m--infixl 7 *.---- | flipped multiplicative action------ > (*.) == flip (.*)-(*.) :: (MultiplicativeAction m a) => m -> a -> m-(*.) = flip (.*)---- | Divisive Action-class- (Divisive a) =>- DivisiveAction m a- | m -> a- where- infixl 7 ./- (./) :: a -> m -> 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>------ > a .* one == a--- > (a + b) .* c == (a .* c) + (b .* c)--- > c *. (a + b) == (c *. a) + (c *. b)--- > a .* zero == zero--- > a .* b == b *. a-class (Distributive a, MultiplicativeAction m a) => Module m a
src/NumHask/Algebra/Multiplicative.hs view
@@ -1,6 +1,3 @@-{-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_GHC -Wno-unused-imports #-}- -- | Multiplicative classes module NumHask.Algebra.Multiplicative ( Multiplicative (..),@@ -73,6 +70,8 @@ -- >>> 1 / 2 -- 0.5 class (Multiplicative a) => Divisive a where+ {-# MINIMAL (/) | recip #-}+ recip :: a -> a recip a = one / a
src/NumHask/Algebra/Ring.hs view
@@ -1,7 +1,3 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}- -- | Ring classes module NumHask.Algebra.Ring ( Distributive,@@ -34,41 +30,7 @@ -- prop> \a -> a * zero == zero -- -- The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element Absorption> 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) =>- 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)+type Distributive a = (Additive a, Multiplicative a) -- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian group under addition ('NumHask.Algebra.Unital', 'NumHask.Algebra.Associative', 'NumHask.Algebra.Commutative', 'NumHask.Algebra.Invertible') and monoidal under multiplication ('NumHask.Algebra.Unital', 'NumHask.Algebra.Associative'), and where multiplication distributes over addition. --@@ -87,34 +49,26 @@ -- > \a b c -> (a + b) * c == a * c + b * c -- > \a -> zero * a == zero -- > \a -> a * zero == zero-class- (Distributive a, Subtractive a) =>- Ring a--instance- (Distributive a, Subtractive a) =>- Ring a+type Ring a = (Distributive a, Subtractive a) -- | A <https://en.wikipedia.org/wiki/Semiring#Star_semirings StarSemiring> is a semiring with an additional unary operator (star) satisfying: -- -- > \a -> star a == one + a * star a class (Distributive a) => StarSemiring a where+ {-# MINIMAL star | plus #-}+ star :: a -> a star a = one + plus a plus :: a -> a plus a = a * star a -instance (StarSemiring b) => StarSemiring (a -> b)- -- | A <https://en.wikipedia.org/wiki/Kleene_algebra Kleene Algebra> is a Star Semiring with idempotent addition. -- -- > a * x + x = a ==> star a * x + x = x -- > x * a + x = a ==> x * star a + x = x class (StarSemiring a, Idempotent a) => KleeneAlgebra a -instance (KleeneAlgebra b) => KleeneAlgebra (a -> b)- -- | Involutive Ring -- -- > adj (a + b) ==> adj a + adj b@@ -154,8 +108,6 @@ instance InvolutiveRing Word32 instance InvolutiveRing Word64--instance (InvolutiveRing b) => InvolutiveRing (a -> b) -- | Defining 'two' requires adding the multiplicative unital to itself. In other words, the concept of 'two' is a Ring one. --
src/NumHask/Data/Complex.hs view
@@ -1,21 +1,18 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RebindableSyntax #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} -- | Complex numbers. module NumHask.Data.Complex ( Complex (..),+ (+:), realPart, imagPart, ) where import Data.Data (Data)-import GHC.Generics (Generic, Generic1)+import GHC.Generics import NumHask.Algebra.Additive import NumHask.Algebra.Field import NumHask.Algebra.Lattice@@ -27,130 +24,97 @@ ( Num (..), atan, atan2,+ ceiling, cos, exp,+ floor, fromIntegral, log, negate, pi,+ properFraction, recip,+ round, sin, sqrt,+ truncate, (/), )-import qualified Prelude as P (Ord (..), otherwise, (&&), (<), (<=), (==), (>)) --- -------------------------------------------------------------------------------- The Complex type-infix 6 :+---- | Complex numbers have real and imaginary parts.------ The 'Data.Foldable.Foldable' and 'Data.Traversable.Traversable' instances traverse the real part first.-data Complex a- = -- | forms a complex number from its real and imaginary- -- rectangular components.- !a :+ !a- deriving+-- | The underlying representation is a newtype-wrapped tuple, compared with the base datatype. This was chosen to facilitate the use of DerivingVia.+newtype Complex a = Complex {complexPair :: (a, a)}+ deriving stock ( Eq, Show, Read, Data, Generic,- Generic1,- Functor,- Foldable,- Traversable+ Functor )+ deriving+ ( Additive,+ Subtractive,+ Basis,+ Direction,+ Epsilon,+ JoinSemiLattice,+ MeetSemiLattice,+ BoundedJoinSemiLattice,+ BoundedMeetSemiLattice,+ ExpField+ )+ via (EuclideanPair a) +infixl 6 +:++-- | Complex number constructor.+(+:) :: a -> a -> Complex a+(+:) r i = Complex (r, i)+ -- | Extracts the real part of a complex number. realPart :: Complex a -> a-realPart (x :+ _) = x+realPart (Complex (x, _)) = x -- | Extracts the imaginary part of a complex number. imagPart :: Complex a -> a-imagPart (_ :+ y) = y--instance (Additive a) => Additive (Complex a) where- (rx :+ ix) + (ry :+ iy) = (rx + ry) :+ (ix + iy)- zero = zero :+ zero--instance (Subtractive a) => Subtractive (Complex a) where- negate (rx :+ ix) = negate rx :+ negate ix--instance- (Distributive a, Subtractive a) =>- Distributive (Complex a)+imagPart (Complex (_, y)) = y instance (Subtractive a, Multiplicative a) => Multiplicative (Complex a) where- (rx :+ ix) * (ry :+ iy) =- (rx * ry - ix * iy) :+ (ix * ry + iy * rx)- one = one :+ zero+ (Complex (r, i)) * (Complex (r', i')) =+ Complex (r * r' - i * i', i * r' + i' * r)+ one = one +: zero instance (Subtractive a, Divisive a) => Divisive (Complex a) where- recip (rx :+ ix) = (rx * d) :+ (negate ix * d)+ recip (Complex (r, i)) = (r * d) +: (negate i * d) where- d = recip ((rx * rx) + (ix * ix))+ d = recip ((r * r) + (i * i)) instance (Additive a, FromIntegral a b) => FromIntegral (Complex a) b where- fromIntegral x = fromIntegral x :+ zero---- | A euclidean-style norm is strong convention for Complex.-instance- (ExpField a) =>- Norm (Complex a) a- where- norm (rx :+ ix) = sqrt (rx * rx + ix * ix)- basis x@(rx :+ ix) = rx / norm x :+ ix / norm x--instance (TrigField a) => Direction (Complex a) a where- angle (x :+ y) = atan2 y x- ray x = cos x :+ sin x--instance- (Ord a, Signed a, Epsilon a, Subtractive a) =>- Epsilon (Complex a)- where- epsilon = epsilon :+ epsilon-- nearZero (ar :+ ai) = ar <= epsilon && ai <= epsilon--instance (Field a) => Field (Complex a)--instance (Ord a, TrigField a, ExpField a) => ExpField (Complex a) where- exp (rx :+ ix) = (exp rx * cos ix) :+ (exp rx * sin ix)- log (rx :+ ix) = log (sqrt (rx * rx + ix * ix)) :+ atan2' ix rx- where- atan2' y x- | x P.> zero = atan (y / x)- | x P.== zero P.&& y P.> zero = pi / (one + one)- | x P.< one P.&& y P.> one = pi + atan (y / x)- | (x P.<= zero P.&& y P.< zero) || (x P.< zero) =- negate (atan2' (negate y) x)- | y P.== zero = pi -- must be after the previous test on zero y- | x P.== zero P.&& y P.== zero = y -- must be after the other double zero tests- | P.otherwise = x + y -- x or y is a NaN, return a NaN (via +)+ fromIntegral x = fromIntegral x +: zero instance (Distributive a, Subtractive a) => InvolutiveRing (Complex a) where- adj (a :+ b) = a :+ negate b--instance (JoinSemiLattice a) => JoinSemiLattice (Complex a) where- (\/) (ar :+ ai) (br :+ bi) = (ar \/ br) :+ (ai \/ bi)+ adj (Complex (r, i)) = r +: negate i -instance (MeetSemiLattice a) => MeetSemiLattice (Complex a) where- (/\) (ar :+ ai) (br :+ bi) = (ar /\ br) :+ (ai /\ bi)+-- Can't use DerivingVia due to extra Whole constraints+instance (Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (Complex a) where+ type Whole (Complex a) = Complex (Whole a) -instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (Complex a) where- bottom = bottom :+ bottom+ properFraction (Complex (x, y)) =+ (Complex (xwhole, ywhole), Complex (xfrac, yfrac))+ where+ (xwhole, xfrac) = properFraction x+ (ywhole, yfrac) = properFraction y -instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (Complex a) where- top = top :+ top+ round (Complex (x, y)) = Complex (round x, round y)+ ceiling (Complex (x, y)) = Complex (ceiling x, ceiling y)+ floor (Complex (x, y)) = Complex (floor x, floor y)+ truncate (Complex (x, y)) = Complex (truncate x, truncate y)
src/NumHask/Data/Integral.hs view
@@ -1,16 +1,10 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE TypeFamilies #-}-{-# OPTIONS_GHC -Wall #-}- -- | Integral classes module NumHask.Data.Integral ( Integral (..), ToIntegral (..),+ ToInt, FromIntegral (..),+ FromInt, FromInteger (..), even, odd,@@ -129,6 +123,9 @@ toIntegral :: a -> b +-- | Convert to an 'Int'+type ToInt a = ToIntegral a Int+ instance ToIntegral Integer Integer where toIntegral = P.id @@ -239,6 +236,9 @@ fromIntegral :: b -> a +-- | Convert from an 'Int'+type FromInt a = FromIntegral a Int+ instance (FromIntegral a b) => FromIntegral (c -> a) b where fromIntegral i _ = fromIntegral i @@ -362,7 +362,7 @@ -- -- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that constraints on 'fromInteger' need to be in a form @C v@, where v is a Num or a subclass of Num. ----- So a type synonym of `type FromInteger a = FromIntegral a Integer` doesn't work well with type defaulting; hence the need for a separate class.+-- So a type synonym such as @type FromInteger a = FromIntegral a Integer@ doesn't work well with type defaulting; hence the need for a separate class. class FromInteger a where fromInteger :: Integer -> a @@ -453,7 +453,7 @@ -- | raise a number to an 'Int' power ----- Note: This differs from (^) found in prelude which is a partial function (it errors on negative integrals). This monomorphic version is provided to help reduce ambiguous type noise in common usages of this sign.+-- Note: This differs from (^) found in prelude which is a partial function (it errors on negative integrals). This is a monomorphic version of '(^^)' provided to help reduce ambiguous type noise in common usages. -- -- >>> 2 ^ 3 -- 8.0
src/NumHask/Data/Rational.hs view
@@ -1,11 +1,5 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE UndecidableInstances #-} -- | Rational classes module NumHask.Data.Rational@@ -43,7 +37,7 @@ -- | A rational number data Ratio a = !a :% !a deriving (P.Show) -instance (P.Eq a, Subtractive a, Signed a, Integral a) => P.Eq (Ratio a) where+instance (P.Eq a, Subtractive a, EndoBased a, Absolute a, Integral a) => P.Eq (Ratio a) where a@(xa :% ya) == b@(xb :% yb) | isRNaN a P.|| isRNaN b = P.False | xa == zero P.&& xb == zero = P.True@@ -58,11 +52,11 @@ | x P.== zero P.&& y P.== zero = P.True | P.otherwise = P.False -instance (P.Ord a, Integral a, Signed a, Subtractive a) => P.Ord (Ratio a) where+instance (P.Ord a, Integral a, EndoBased a, Subtractive 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, Signed a, Integral a, Ring a) => Additive (Ratio a) where+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Additive (Ratio a) where (x :% y) + (x' :% y') | y P.== zero P.&& y' P.== zero = bool one (negate one) (x + x' P.< zero) :% zero | y P.== zero = x :% y@@ -71,48 +65,43 @@ zero = zero :% one -instance (P.Ord a, Signed a, Integral a, Ring a) => Subtractive (Ratio a) where+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Subtractive (Ratio a) where negate (x :% y) = negate x :% y -instance (P.Ord a, Signed a, Integral a, Ring a) => Multiplicative (Ratio a) where+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Multiplicative (Ratio a) where (x :% y) * (x' :% y') = reduce (x * x') (y * y') one = one :% one instance- (P.Ord a, Signed a, Integral a, Ring a) =>+ (P.Ord a, EndoBased a, Integral a, Ring a) => Divisive (Ratio a) where recip (x :% y)- | sign x P.== negate one = negate y :% negate x+ | signum x P.== negate one = negate y :% negate x | P.otherwise = y :% x -instance (P.Ord a, Signed a, Integral a, Ring a) => Distributive (Ratio a)--instance (P.Ord a, Signed a, Integral a, Ring a) => Field (Ratio a)--instance (P.Ord a, P.Ord b, Signed a, Integral a, Ring a, Signed b, Subtractive b, Integral 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, EndoBased a, Absolute a, ToInt a, Integral a, Ring a) => QuotientField (Ratio a) where+ type Whole (Ratio a) = Int+ properFraction (n :% d) = let (w, r) = quotRem n d in (toIntegral w, r :% d) -instance (P.Ord a, Signed a, Integral a, Ring a) => Signed (Ratio a) where- sign (n :% _) =+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Basis (Ratio a) where+ type Mag (Ratio a) = Ratio a+ type Base (Ratio a) = Ratio a+ basis (n :% _) = case compare n zero of EQ -> zero GT -> one LT -> negate one- abs (n :% d) = abs n :% abs d--instance (P.Ord a, Signed a, Integral a, Ring a) => Norm (Ratio a) (Ratio a) where- norm = abs- basis = sign+ magnitude (n :% d) = abs n :% abs d -instance (P.Ord a, Integral a, Signed a, Subtractive a) => JoinSemiLattice (Ratio a) where+instance (P.Ord a, Integral a, EndoBased a, Subtractive a) => JoinSemiLattice (Ratio a) where (\/) = P.min -instance (P.Ord a, Integral a, Signed a, Subtractive a) => MeetSemiLattice (Ratio a) where+instance (P.Ord a, Integral a, EndoBased a, Subtractive a) => MeetSemiLattice (Ratio a) where (/\) = P.max -instance (P.Ord a, Signed a, Integral a, Ring a, MeetSemiLattice a) => Epsilon (Ratio a)+instance (P.Ord a, EndoBased a, Integral a, Ring a, MeetSemiLattice a) => Epsilon (Ratio a) instance (FromIntegral a b, Multiplicative a) => FromIntegral (Ratio a) b where fromIntegral x = fromIntegral x :% one@@ -218,7 +207,7 @@ -- -- prop> \a b -> reduce a b == a :% b || b == zero reduce ::- (P.Eq a, Subtractive a, Signed a, Integral a) => a -> a -> Ratio a+ (P.Eq a, Subtractive a, EndoBased a, Integral a) => a -> a -> Ratio a reduce x y | x P.== zero P.&& y P.== zero = zero :% zero | z P.== zero = one :% zero@@ -226,7 +215,7 @@ where z = gcd x y n % d- | sign d P.== negate one = negate n :% negate d+ | signum 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@@ -241,7 +230,7 @@ -- -- >>> gcd 72 60 -- 12-gcd :: (P.Eq a, Signed a, Integral a) => a -> a -> a+gcd :: (P.Eq a, EndoBased a, Integral a) => a -> a -> a gcd x y = gcd' (abs x) (abs y) where gcd' a b
src/NumHask/Exception.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -Wall #-}- -- | Exceptions arising within numhask. module NumHask.Exception ( NumHaskException (..),
src/NumHask/Prelude.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE RebindableSyntax #-}-{-# OPTIONS_GHC -Wall #-} {-# OPTIONS_HADDOCK prune #-} -- | A prelude composed by overlaying numhask on Prelude, together with a few minor tweaks needed for RebindableSyntax.@@ -9,7 +7,7 @@ module NumHask.Algebra.Field, module NumHask.Algebra.Group, module NumHask.Algebra.Lattice,- module NumHask.Algebra.Module,+ module NumHask.Algebra.Action, module NumHask.Algebra.Multiplicative, module NumHask.Algebra.Ring, module NumHask.Algebra.Metric,@@ -25,21 +23,38 @@ fromList, fromListN, Natural (..),+ module GHC.OverloadedLabels, -- * Modules you can't live without module Data.Bool, module Data.Kind, module GHC.Generics,- module Prelude,- module Data.Foldable,+ module Control.Applicative, module Data.Traversable, module Data.Semigroup, module Data.Maybe,++ -- * Data.Function+ module Data.Function,++ -- * Control.Category++ -- Putting id back.+ module Control.Category,++ -- * Data.Foldable+ module Data.Foldable,++ -- * The Prelude+ module Prelude, ) where +import Control.Applicative+import Control.Category import Data.Bool import Data.Foldable hiding (product, sum)+import Data.Function hiding (id, (.)) import Data.Kind import Data.Maybe import Data.Semigroup@@ -47,19 +62,20 @@ import GHC.Exts import GHC.Generics import GHC.Natural (Natural (..))+import GHC.OverloadedLabels+import NumHask.Algebra.Action import NumHask.Algebra.Additive import NumHask.Algebra.Field import NumHask.Algebra.Group import NumHask.Algebra.Lattice import NumHask.Algebra.Metric-import NumHask.Algebra.Module import NumHask.Algebra.Multiplicative import NumHask.Algebra.Ring import NumHask.Data.Complex import NumHask.Data.Integral import NumHask.Data.Rational import NumHask.Exception-import Prelude hiding (Integral (..), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, log, logBase, negate, odd, pi, product, properFraction, recip, round, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, truncate, (*), (**), (+), (-), (/), (^), (^^))+import Prelude hiding (Integral (..), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, id, log, logBase, negate, odd, pi, product, properFraction, recip, round, signum, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, truncate, (*), (**), (+), (-), (.), (/), (^), (^^)) -- $usage --
− test/doctests.hs
@@ -1,8 +0,0 @@-module Main where--main :: IO ()-main = do- putStrLn "This test-suite exists only to add dependencies"- putStrLn "To run doctests: "- putStrLn " cabal build all --enable-tests"- putStrLn " cabal-docspec"