Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Numeric classes.
Synopsis
- class Additive a where
- sum :: (Additive a, Foldable f) => f a -> a
- accsum :: (Additive a, Traversable f) => f a -> f a
- class Additive a => Subtractive a where
- class Multiplicative a where
- product :: (Multiplicative a, Foldable f) => f a -> a
- accproduct :: (Multiplicative a, Traversable f) => f a -> f a
- class Multiplicative a => Divisive a where
- type Distributive a = (Additive a, Multiplicative a)
- type Ring a = (Distributive a, Subtractive a)
- class Distributive a => StarSemiring a where
- class (StarSemiring a, Idempotent a) => KleeneAlgebra a
- class Distributive a => InvolutiveRing a where
- adj :: a -> a
- two :: (Multiplicative a, Additive a) => a
- type Field a = (Ring a, Divisive a)
- class Field a => ExpField a where
- class Field a => QuotientField a where
- class Field a => TrigField a where
- infinity :: Field a => a
- negInfinity :: Field a => a
- nan :: Field a => a
- half :: Field a => a
- class Eq a => JoinSemiLattice a where
- (\/) :: a -> a -> a
- joinLeq :: JoinSemiLattice a => a -> a -> Bool
- (<\) :: JoinSemiLattice a => a -> a -> Bool
- class Eq a => MeetSemiLattice a where
- (/\) :: a -> a -> a
- meetLeq :: MeetSemiLattice a => a -> a -> Bool
- (</) :: MeetSemiLattice a => a -> a -> Bool
- class JoinSemiLattice a => BoundedJoinSemiLattice a where
- bottom :: a
- class MeetSemiLattice a => BoundedMeetSemiLattice a where
- top :: a
- class Additive (AdditiveScalar m) => AdditiveAction m where
- type AdditiveScalar m :: Type
- (|+) :: m -> AdditiveScalar m -> m
- (+|) :: AdditiveAction m => AdditiveScalar m -> m -> m
- class (AdditiveAction m, Subtractive (AdditiveScalar m)) => SubtractiveAction m where
- (|-) :: m -> AdditiveScalar m -> m
- (-|) :: (AdditiveAction m, Subtractive m) => AdditiveScalar m -> m -> m
- class Multiplicative (Scalar m) => MultiplicativeAction m where
- (*|) :: MultiplicativeAction m => Scalar m -> m -> m
- class (Divisive (Scalar m), MultiplicativeAction m) => DivisiveAction m where
- (/|) :: (MultiplicativeAction m, Divisive m) => Scalar m -> m -> m
- type Module m = (Distributive (Scalar m), MultiplicativeAction m)
- class Distributive (Mag a) => Basis a where
- type Absolute a = (Basis a, Mag a ~ a)
- type Sign a = (Basis a, Base a ~ a)
- type EndoBased a = (Basis a, Mag a ~ a, Base a ~ a)
- abs :: Absolute a => a -> a
- signum :: Sign a => a -> a
- distance :: (Basis a, Subtractive a) => a -> a -> Mag a
- class (Distributive coord, Distributive (Dir coord)) => Direction coord where
- data Polar a = Polar {}
- polar :: (Dir (Base a) ~ Mag a, Basis a, Direction (Base a)) => a -> Polar (Mag a)
- coord :: (Scalar m ~ Dir m, MultiplicativeAction m, Direction m) => Polar (Scalar m) -> m
- class (Eq a, Additive a) => Epsilon a where
- epsilon :: a
- aboutEqual :: (Epsilon a, Lattice a, Subtractive a) => a -> a -> Bool
- nearZero :: (Epsilon a, Lattice a, Subtractive a) => a -> Bool
- (~=) :: Epsilon a => (Lattice a, Subtractive a) => a -> a -> Bool
- newtype Complex a = Complex {
- complexPair :: (a, a)
- (+:) :: a -> a -> Complex a
- realPart :: Complex a -> a
- imagPart :: Complex a -> a
- class Distributive a => Integral a where
- class ToIntegral a b where
- toIntegral :: a -> b
- type ToInt a = ToIntegral a Int
- class FromIntegral a b where
- fromIntegral :: b -> a
- class FromInteger a where
- fromInteger :: Integer -> a
- type FromInt a = FromIntegral a Int
- even :: (Eq a, Integral a) => a -> Bool
- odd :: (Eq a, Integral a) => a -> Bool
- (^^) :: (Ord b, Divisive a, Subtractive b, Integral b) => a -> b -> a
- (^) :: Divisive a => a -> Int -> a
- data Ratio a = !a :% !a
- type Rational = Ratio Integer
- class ToRatio a b where
- class FromRatio a b where
- class FromRational a where
- fromRational :: Rational -> a
- reduce :: (Eq a, Subtractive a, EndoBased a, Integral a) => a -> a -> Ratio a
- gcd :: (Eq a, EndoBased a, Integral a) => a -> a -> a
- newtype NumHaskException = NumHaskException {}
- throw :: forall (r :: RuntimeRep) (a :: TYPE r) e. Exception e => e -> a
Usage
>>>
:set -XRebindableSyntax
>>>
import NumHask.Prelude
>>>
1+1
2
Overview
numhask is largely a set of classes that can replace the Num
class and it's descendents.
Principles that have guided design include:
- balanced class density. The numeric hierarchy 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.
- operator-first. In all cases, a class exists to define useful operators.
Major class groupings, such as
Distributive
,Ring
andField
are type synonyms. - 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:
Int
,Integer
,Double
,Float
,Natural
, and the Word classes. It avoids name (or idea) clashes with other popular libraries and adopts conventions in the current prelude where they make sense. - proof-of-concept. The library may be below industrial-strength depending on a definition of this term. At the same time, correspondence around improving the library is most welcome.
The class heirarchy looks somewhat like this:
Prelude Mappings
Num
is a very old part of haskell, and is virtually unchanged since its specification in
haskell98.
A deconstruction of Num
and mapping to numhask.
-- | Basic numeric class. class Num a where {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-} (+), (-), (*) :: a -> a -> a -- | Unary negation. negate :: a -> a
(+)
is an operator of the Additive
class
(-)
& negate
are functions in the Subtractive
class, and
(*)
is an operator of the Multiplicative
class.
zero
and one
are also introduced to the numeric hierarchy.
-- | Absolute value. abs :: a -> a -- | Sign of a number. -- The functions 'abs' and 'signum' should satisfy the law: -- -- > abs x * signum x == x -- -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero) -- or @1@ (positive). signum :: a -> a
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.
A new class, Basis
is supplied to handle these situations:
abs
and 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', -- so such literals have type @('Num' a) => a@. fromInteger :: Integer -> a
FromInteger
becomes its own class and FromIntegral
is introduced to polymorphise the covariant.
Mappings from other areas of prelude include:
Integral
becomesIntegral
and a polymorphicToIntegral
is introduced.Fractional
is roughly synonymous toField
together with a polymorphicFromRatio
.RealFrac
becomesQuotientField
with a polymorphicWhole
type using Type Families.Floating
is split intoExpField
andTrigField
RealFloat
is not attempted. Life is too short.- Complex is resupplied in
Complex
but with some functionality deriving viaEuclideanPair
. The underlying representation has also been switched to a newtype-wrapped tuple.
In addition to base changes, alternatives to sum
and product
from Foldable
are also supplied.
Extensions
RebindableSyntax is recommended for use with numhask.
As a replacement for the numerical classes, numhask clashes significantly with an
unqualified import of the Prelude
. Either numhask modules should be qualified,
or prelude turned off with the NoImplicitPrelude extension, or with RebindableSyntax,
which implies NoImplicitPrelude.
defaulting
Without RebindableSyntax, numeric literals default as follows:
>>>
:set -XNoRebindableSyntax
>>>
:t 1
1 :: Num a => a
>>>
:t 1.0
1.0 :: Fractional a => a
With RebindableSyntax (which also switches NoImplicitPrelude on) literal numbers change to the numhask types, FromInteger
and FromRational
:
>>>
:set -XRebindableSyntax
>>>
:t 1
1 :: FromInteger a => a
>>>
:t 1.0
1.0 :: FromRational a => a
>>>
1
1
>>>
1.0
1.0
RebindableSyntax is a tradeoff, however, and usage comes attached with other non-numeric changes that NumHask.Prelude attempts to counteract.
See haskell2010 Section 4.3.4 for the nuts and bolts to defaulting.
The effect of ExtendedDefaultRules
in ghci or switched on as an extension also need to be understood.
It can lead to unusual interactions with numerics and strange error messages at times because
it adds ()
and []
to the start of the type defaulting list.
Additive
class Additive a where Source #
or Addition
For practical reasons, we begin the class tree with Additive
. Starting with Associative
and Unital
, or using Semigroup
and Monoid
from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.
\a -> zero + a == a
\a -> a + zero == a
\a b c -> (a + b) + c == a + (b + c)
\a b -> a + b == b + a
By convention, (+) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative addition seems a bit dogmatic.
>>>
zero + 1
1
>>>
1 + 1
2
Instances
Additive Int16 Source # | |
Additive Int32 Source # | |
Additive Int64 Source # | |
Additive Int8 Source # | |
Additive Word16 Source # | |
Additive Word32 Source # | |
Additive Word64 Source # | |
Additive Word8 Source # | |
Additive Integer Source # | |
Additive Natural Source # | |
Additive Bool Source # | |
Additive Double Source # | |
Additive Float Source # | |
Additive Int Source # | |
Additive Word Source # | |
Additive a => Additive (Sum a) Source # | |
Additive a => Additive (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric (+) :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # zero :: EuclideanPair a Source # | |
Additive a => Additive (Complex a) Source # | |
(Ord a, EndoBased a, Integral a, Ring a) => Additive (Ratio a) Source # | |
Additive b => Additive (a -> b) Source # | |
sum :: (Additive a, Foldable f) => f a -> a Source #
Compute the sum of a Foldable
.
>>>
sum [0..10]
55
accsum :: (Additive a, Traversable f) => f a -> f a Source #
Compute the accumulating sum of a Traversable
.
>>>
accsum [0..10]
[0,1,3,6,10,15,21,28,36,45,55]
class Additive a => Subtractive a where Source #
or Subtraction
\a -> a - a == zero
\a -> negate a == zero - a
\a -> negate a + a == zero
\a -> a + negate a == zero
>>>
negate 1
-1
>>>
1 - 2
-1
Instances
Subtractive Int16 Source # | |
Subtractive Int32 Source # | |
Subtractive Int64 Source # | |
Subtractive Int8 Source # | |
Subtractive Word16 Source # | |
Subtractive Word32 Source # | |
Subtractive Word64 Source # | |
Subtractive Word8 Source # | |
Subtractive Integer Source # | |
Subtractive Natural Source # | |
Subtractive Double Source # | |
Subtractive Float Source # | |
Subtractive Int Source # | |
Subtractive Word Source # | |
Subtractive a => Subtractive (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric negate :: EuclideanPair a -> EuclideanPair a Source # (-) :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # | |
Subtractive a => Subtractive (Complex a) Source # | |
(Ord a, EndoBased a, Integral a, Ring a) => Subtractive (Ratio a) Source # | |
Subtractive b => Subtractive (a -> b) Source # | |
Multiplicative
class Multiplicative a where Source #
For practical reasons, we begin the class tree with Additive
and Multiplicative
. Starting with Associative
and Unital
, or using Semigroup
and Monoid
from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.
\a -> one * a == a
\a -> a * one == a
\a b c -> (a * b) * c == a * (b * c)
By convention, (*) is regarded as not necessarily commutative, but this is not universal, and the introduction of another symbol which means commutative multiplication seems a bit dogmatic.
>>>
one * 2
2
>>>
2 * 3
6
Instances
Multiplicative Int16 Source # | |
Multiplicative Int32 Source # | |
Multiplicative Int64 Source # | |
Multiplicative Int8 Source # | |
Multiplicative Word16 Source # | |
Multiplicative Word32 Source # | |
Multiplicative Word64 Source # | |
Multiplicative Word8 Source # | |
Multiplicative Integer Source # | |
Multiplicative Natural Source # | |
Multiplicative Bool Source # | |
Multiplicative Double Source # | |
Multiplicative Float Source # | |
Multiplicative Int Source # | |
Multiplicative Word Source # | |
Multiplicative a => Multiplicative (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric (*) :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # one :: EuclideanPair a Source # | |
(Subtractive a, Multiplicative a) => Multiplicative (Complex a) Source # | |
(Ord a, EndoBased a, Integral a, Ring a) => Multiplicative (Ratio a) Source # | |
Multiplicative b => Multiplicative (a -> b) Source # | |
product :: (Multiplicative a, Foldable f) => f a -> a Source #
Compute the product of a Foldable
.
>>>
product [1..5]
120
accproduct :: (Multiplicative a, Traversable f) => f a -> f a Source #
Compute the accumulating product of a Traversable
.
>>>
accproduct [1..5]
[1,2,6,24,120]
class Multiplicative a => Divisive a where Source #
or Division
Though unusual, the term Divisive usefully fits in with the grammer of other classes and avoids name clashes that occur with some popular libraries.
\(a :: Double) -> a / a ~= one || a == zero
\(a :: Double) -> recip a ~= one / a || a == zero
\(a :: Double) -> recip a * a ~= one || a == zero
\(a :: Double) -> a * recip a ~= one || a == zero
>>>
recip 2.0
0.5
>>>
1 / 2
0.5
Instances
Divisive Double Source # | |
Divisive Float Source # | |
(Subtractive a, Divisive a) => Divisive (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric recip :: EuclideanPair a -> EuclideanPair a Source # (/) :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # | |
(Subtractive a, Divisive a) => Divisive (Complex a) Source # | |
(Ord a, EndoBased a, Integral a, Ring a) => Divisive (Ratio a) Source # | |
Divisive b => Divisive (a -> b) Source # | |
Ring
type Distributive a = (Additive a, Multiplicative a) Source #
\a b c -> a * (b + c) == a * b + a * c
\a b c -> (a + b) * c == a * c + b * c
\a -> zero * a == zero
\a -> a * zero == zero
The sneaking in of the Absorption laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.
type Ring a = (Distributive a, Subtractive a) Source #
A Ring is an abelian group under addition (Unital
, Associative
, Commutative
, Invertible
) and monoidal under multiplication (Unital
, Associative
), and where multiplication distributes over addition.
\a -> zero + a == a \a -> a + zero == a \a b c -> (a + b) + c == a + (b + c) \a b -> a + b == b + a \a -> a - a == zero \a -> negate a == zero - a \a -> negate a + a == zero \a -> a + negate a == zero \a -> one * a == a \a -> a * one == a \a b c -> (a * b) * c == a * (b * c) \a b c -> a * (b + c) == a * b + a * c \a b c -> (a + b) * c == a * c + b * c \a -> zero * a == zero \a -> a * zero == zero
class Distributive a => StarSemiring a where Source #
A StarSemiring is a semiring with an additional unary operator (star) satisfying:
\a -> star a == one + a * star a
class (StarSemiring a, Idempotent a) => KleeneAlgebra a Source #
A 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 Distributive a => InvolutiveRing a where Source #
Involutive Ring
adj (a + b) ==> adj a + adj b adj (a * b) ==> adj a * adj b adj one ==> one adj (adj a) ==> a
Note: elements for which adj a == a
are called "self-adjoint".
Nothing
Instances
two :: (Multiplicative a, Additive a) => a Source #
Field
type Field a = (Ring a, Divisive a) Source #
A Field is a set on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.
A summary of the rules inherited from super-classes of Field:
zero + a == a a + zero == a ((a + b) + c) (a + (b + c)) a + b == b + a a - a == zero negate a == zero - a negate a + a == zero a + negate a == zero one * a == a a * one == a ((a * b) * c) == (a * (b * c)) (a * (b + c)) == (a * b + a * c) ((a + b) * c) == (a * c + b * c) a * zero == zero zero * a == zero a / a == one || a == zero recip a == one / a || a == zero recip a * a == one || a == zero a * recip a == one || a == zero
class Field a => ExpField a where Source #
A hyperbolic field class
\a -> a < zero || (sqrt . (**2)) a == a
\a -> a < zero || (log . exp) a ~= a
\a b -> (b < zero) || a <= zero || a == 1 || abs (a ** logBase a b - b) < 10 * epsilon
logBase :: a -> a -> a Source #
log to the base of
>>>
logBase 2 8
2.9999999999999996
square root
>>>
sqrt 4
2.0
Instances
ExpField Double Source # | |
ExpField Float Source # | |
(Ord a, TrigField a, ExpField a) => ExpField (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric exp :: EuclideanPair a -> EuclideanPair a Source # log :: EuclideanPair a -> EuclideanPair a Source # (**) :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # logBase :: EuclideanPair a -> EuclideanPair a -> EuclideanPair a Source # sqrt :: EuclideanPair a -> EuclideanPair a Source # | |
(Ord a, TrigField a, ExpField a) => ExpField (Complex a) Source # | |
ExpField b => ExpField (a -> b) Source # | |
class Field a => QuotientField a where Source #
properFraction :: a -> (Whole a, a) Source #
round :: (Eq (Whole a), Ring (Whole a)) => a -> Whole a Source #
round to the nearest Int
Exact ties are managed by rounding down ties if the whole component is even.
>>>
round (1.5 :: Double)
2
>>>
round (2.5 :: Double)
2
ceiling :: Distributive (Whole a) => a -> Whole a Source #
supply the next upper whole component
>>>
ceiling (1.001 :: Double)
2
floor :: Ring (Whole a) => a -> Whole a Source #
supply the previous lower whole component
>>>
floor (1.001 :: Double)
1
truncate :: Ring (Whole a) => a -> Whole a Source #
supply the whole component closest to zero
>>>
floor (-1.001 :: Double)
-2
>>>
truncate (-1.001 :: Double)
-1
Instances
QuotientField Double Source # | |
QuotientField Float Source # | |
(Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric type Whole (EuclideanPair a) Source # properFraction :: EuclideanPair a -> (Whole (EuclideanPair a), EuclideanPair a) Source # round :: EuclideanPair a -> Whole (EuclideanPair a) Source # ceiling :: EuclideanPair a -> Whole (EuclideanPair a) Source # floor :: EuclideanPair a -> Whole (EuclideanPair a) Source # truncate :: EuclideanPair a -> Whole (EuclideanPair a) Source # | |
(Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (Complex a) Source # | |
Defined in NumHask.Data.Complex | |
(Ord a, EndoBased a, Absolute a, ToInt a, Integral a, Ring a) => QuotientField (Ratio a) Source # | |
Defined in NumHask.Data.Rational |
class Field a => TrigField a where Source #
Trigonometric Field
The list of laws is quite long: trigonometric identities
Instances
negInfinity :: Field a => a Source #
negative infinity
>>>
negInfinity + infinity
NaN
nan is defined as zero/zero
but note the (social) law:
>>>
nan == zero / zero
False
Lattice
class Eq a => JoinSemiLattice a where Source #
A algebraic structure with element joins: See Semilattice
Associativity: x \/ (y \/ z) == (x \/ y) \/ z Commutativity: x \/ y == y \/ x Idempotency: x \/ x == x
Instances
joinLeq :: JoinSemiLattice a => a -> a -> Bool Source #
The partial ordering induced by the join-semilattice structure
(<\) :: JoinSemiLattice a => a -> a -> Bool infixr 6 Source #
The partial ordering induced by the join-semilattice structure
class Eq a => MeetSemiLattice a where Source #
A algebraic structure with element meets: See Semilattice
Associativity: x /\ (y /\ z) == (x /\ y) /\ z Commutativity: x /\ y == y /\ x Idempotency: x /\ x == x
Instances
meetLeq :: MeetSemiLattice a => a -> a -> Bool Source #
The partial ordering induced by the meet-semilattice structure
(</) :: MeetSemiLattice a => a -> a -> Bool infixr 6 Source #
The partial ordering induced by the meet-semilattice structure
class JoinSemiLattice a => BoundedJoinSemiLattice a where Source #
Instances
class MeetSemiLattice a => BoundedMeetSemiLattice a where Source #
Instances
Action
class Additive (AdditiveScalar m) => AdditiveAction m where Source #
Additive Action
m |+ zero == m
type AdditiveScalar m :: Type Source #
(|+) :: m -> AdditiveScalar m -> m infixl 6 Source #
(+|) :: AdditiveAction m => AdditiveScalar m -> m -> m infixl 6 Source #
flipped additive action
(+|) == flip (|+) zero +| m = m
class (AdditiveAction m, Subtractive (AdditiveScalar m)) => SubtractiveAction m where Source #
Subtractive Action
m |- zero = m
(|-) :: m -> AdditiveScalar m -> m infixl 6 Source #
(-|) :: (AdditiveAction m, Subtractive m) => AdditiveScalar m -> m -> m infixl 6 Source #
Subtraction with the scalar on the left
(-|) == (+|) . negate zero -| m = negate m
class Multiplicative (Scalar m) => MultiplicativeAction m where Source #
Multiplicative Action
m |* one = m m |* zero = zero
Instances
Multiplicative a => MultiplicativeAction (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric type Scalar (EuclideanPair a) Source # (|*) :: EuclideanPair a -> Scalar (EuclideanPair a) -> EuclideanPair a Source # |
(*|) :: MultiplicativeAction m => Scalar m -> m -> m infixl 7 Source #
flipped multiplicative action
(*|) == flip (|*) one *| m = one zero *| m = zero
class (Divisive (Scalar m), MultiplicativeAction m) => DivisiveAction m where Source #
Divisive Action
m |/ one = m
Instances
Divisive a => DivisiveAction (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric (|/) :: EuclideanPair a -> Scalar (EuclideanPair a) -> EuclideanPair a Source # |
(/|) :: (MultiplicativeAction m, Divisive m) => Scalar m -> m -> m Source #
left scalar division
(/|) == (*|) . recip one |/ m = recip m
type Module m = (Distributive (Scalar m), MultiplicativeAction m) Source #
A 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
Metric
class Distributive (Mag a) => Basis a where Source #
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:
\a -> magnitude a >= zero \a -> magnitude zero == zero \a -> a == magnitude a *| basis a \a -> magnitude (basis a) == one
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.
>>>
magnitude (-0.5 :: Double)
0.5
>>>
basis (-0.5 :: Double)
-1.0
Instances
Basis Int16 Source # | |
Basis Int32 Source # | |
Basis Int64 Source # | |
Basis Int8 Source # | |
Basis Word16 Source # | |
Basis Word32 Source # | |
Basis Word64 Source # | |
Basis Word8 Source # | |
Basis Integer Source # | |
Basis Natural Source # | |
Basis Double Source # | |
Basis Float Source # | |
Basis Int Source # | |
Basis Word Source # | |
(ExpField a, Eq a) => Basis (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric type Mag (EuclideanPair a) Source # type Base (EuclideanPair a) Source # magnitude :: EuclideanPair a -> Mag (EuclideanPair a) Source # basis :: EuclideanPair a -> Base (EuclideanPair a) Source # | |
(Additive a, Multiplicative a) => Basis (Polar a) Source # | |
(ExpField a, Eq a) => Basis (Complex a) Source # | |
(Ord a, EndoBased a, Integral a, Ring a) => Basis (Ratio a) Source # | |
type Absolute a = (Basis a, Mag a ~ a) Source #
Basis where the domain and magnitude codomain are the same.
type EndoBased a = (Basis a, Mag a ~ a, Base a ~ a) Source #
Basis where the domain, magnitude codomain and basis codomain are the same.
abs :: Absolute a => a -> a Source #
The absolute value of a number.
\a -> abs a * signum a ~= a
>>>
abs (-1)
1
signum :: Sign a => a -> a Source #
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
distance :: (Basis a, Subtractive a) => a -> a -> Mag a Source #
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
class (Distributive coord, Distributive (Dir coord)) => Direction coord where Source #
Convert between a "co-ordinated" or "higher-kinded" number and a direction.
ray . angle == basis magnitude (ray x) == one
Instances
TrigField a => Direction (EuclideanPair a) Source # | |
Defined in NumHask.Algebra.Metric type Dir (EuclideanPair a) Source # angle :: EuclideanPair a -> Dir (EuclideanPair a) Source # ray :: Dir (EuclideanPair a) -> EuclideanPair a Source # | |
TrigField a => Direction (Complex a) Source # | |
Something that has a magnitude and a direction, with both expressed as the same type.
Instances
Generic (Polar a) Source # | |
Show a => Show (Polar a) Source # | |
Eq a => Eq (Polar a) Source # | |
(Additive a, Multiplicative a) => Basis (Polar a) Source # | |
type Rep (Polar a) Source # | |
Defined in NumHask.Algebra.Metric type Rep (Polar a) = D1 ('MetaData "Polar" "NumHask.Algebra.Metric" "numhask-0.11.1.0-EApRBSOlfGg2K23zs0vJ5I" 'False) (C1 ('MetaCons "Polar" 'PrefixI 'True) (S1 ('MetaSel ('Just "radial") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a) :*: S1 ('MetaSel ('Just "azimuth") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a))) | |
type Base (Polar a) Source # | |
Defined in NumHask.Algebra.Metric | |
type Mag (Polar a) Source # | |
Defined in NumHask.Algebra.Metric |
polar :: (Dir (Base a) ~ Mag a, Basis a, Direction (Base a)) => a -> Polar (Mag a) Source #
Convert a higher-kinded number that has direction, to a Polar
coord :: (Scalar m ~ Dir m, MultiplicativeAction m, Direction m) => Polar (Scalar m) -> m Source #
Convert a Polar to a (higher-kinded) number that has a direction.
class (Eq a, Additive a) => Epsilon a where Source #
A small number, especially useful for approximate equality.
Nothing
Instances
aboutEqual :: (Epsilon a, Lattice a, Subtractive a) => a -> a -> Bool Source #
Approximate equality
>>>
aboutEqual zero (epsilon :: Double)
True
nearZero :: (Epsilon a, Lattice a, Subtractive a) => a -> Bool Source #
Note that the constraint is Lattice rather than Ord allowing broader usage.
>>>
nearZero (epsilon :: Double)
True
>>>
nearZero (epsilon :: EuclideanPair Double)
True
(~=) :: Epsilon a => (Lattice a, Subtractive a) => a -> a -> Bool infixl 4 Source #
About equal operator.
>>>
(1.0 + epsilon) ~= (1.0 :: Double)
True
Complex
The underlying representation is a newtype-wrapped tuple, compared with the base datatype. This was chosen to facilitate the use of DerivingVia.
Complex | |
|
Instances
Integral
class Distributive a => Integral a where Source #
An Integral is anything that satisfies the law:
\a b -> b == zero || b * (a `div` b) + (a `mod` b) == a
>>>
3 `divMod` 2
(1,1)
>>>
(-3) `divMod` 2
(-2,1)
>>>
(-3) `quotRem` 2
(-1,-1)
div :: a -> a -> a infixl 7 Source #
mod :: a -> a -> a infixl 7 Source #
Instances
class ToIntegral a b where Source #
toIntegral is kept separate from Integral to help with compatability issues.
toIntegral a == a
toIntegral :: a -> b Source #
Instances
class FromIntegral a b where Source #
Polymorphic version of fromInteger
fromIntegral a == a
fromIntegral :: b -> a Source #
Instances
class FromInteger a where Source #
fromInteger
is special in two ways:
- numeric integral literals (like "42") are interpreted specifically as "fromInteger (42 :: GHC.Num.Integer)". The prelude version is used as default (or whatever fromInteger is in scope if RebindableSyntax is set).
- The default rules in haskell2010 specify that constraints on
fromInteger
need to be in a formC v
, where v is a Num or a subclass of Num.
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.
fromInteger :: Integer -> a Source #
Instances
Rational
A rational number
!a :% !a |
Instances
class ToRatio a b where Source #
toRatio is equivalent to Real
in base, but is polymorphic in the Integral type.
>>>
toRatio (3.1415927 :: Float) :: Ratio Integer
13176795 :% 4194304
Instances
class FromRatio a b where Source #
Fractional
in base splits into fromRatio and Field
>>>
fromRatio (5 :% 2 :: Ratio Integer) :: Double
2.5
class FromRational a where Source #
fromRational is special in two ways:
- numeric decimal literals (like "53.66") are interpreted as exactly "fromRational (53.66 :: GHC.Real.Ratio Integer)". The prelude version, GHC.Real.fromRational is used as default (or whatever is in scope if RebindableSyntax is set).
- The default rules in haskell2010 specify that contraints on
fromRational
need to be in a formC v
, where v is a Num or a subclass of Num.
So a type synonym of `type FromRational a = FromRatio a Integer` doesn't work well with type defaulting; hence the need for a separate class.
fromRational :: Rational -> a Source #
Instances
FromRational Double Source # | |
Defined in NumHask.Data.Rational fromRational :: Rational -> Double Source # | |
FromRational Float Source # | |
Defined in NumHask.Data.Rational fromRational :: Rational -> Float Source # | |
FromRational (Ratio Integer) Source # | |
Defined in NumHask.Data.Rational |
reduce :: (Eq a, Subtractive a, EndoBased a, Integral a) => a -> a -> Ratio a Source #
reduce
normalises a ratio by dividing both numerator and denominator by
their greatest common divisor.
>>>
reduce 72 60
6 :% 5
\a b -> reduce a b == a :% b || b == zero
gcd :: (Eq a, EndoBased a, Integral a) => a -> a -> a Source #
is the non-negative factor of both gcd
x yx
and y
of which
every common factor of x
and y
is also a factor; for example
, gcd
4 2 = 2
, gcd
(-4) 6 = 2
= gcd
0 44
.
= gcd
0 00
.
(That is, the common divisor that is "greatest" in the divisibility
preordering.)
Note: Since for signed fixed-width integer types,
,
the result may be negative if one of the arguments is abs
minBound
< 0
(and
necessarily is if the other is minBound
0
or
) for such types.minBound
>>>
gcd 72 60
12
Exceptions
newtype NumHaskException Source #
A numhask exception.
Instances
Exception NumHaskException Source # | |
Defined in NumHask.Exception | |
Show NumHaskException Source # | |
Defined in NumHask.Exception showsPrec :: Int -> NumHaskException -> ShowS # show :: NumHaskException -> String # showList :: [NumHaskException] -> ShowS # |