Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- module Numeric.Decimal.BoundedArithmetic
- newtype Decimal r (s :: Nat) p = Decimal p
- class Integral p => Round r p where
- roundDecimal :: KnownNat k => Decimal r (n + k) p -> Decimal r n p
- wrapDecimal :: Integral p => p -> Decimal r s p
- unwrapDecimal :: Decimal r s p -> p
- splitDecimal :: (Integral p, KnownNat s) => Decimal r s p -> (p, p)
- decimalNumerator :: Integral p => Decimal r s p -> Integer
- decimalDenominator :: KnownNat s => Decimal r s p -> Integer
- getScale :: forall r s p. KnownNat s => Decimal r s p -> Integer
- scaleUp :: forall k r n. KnownNat k => Decimal r n Integer -> Decimal r (n + k) Integer
- scaleUpBounded :: forall k r n p m. (MonadThrow m, Integral p, Bounded p, KnownNat k) => Decimal r n p -> m (Decimal r (n + k) p)
- castRounding :: forall r' r s p. Decimal r s p -> Decimal r' s p
- parseDecimalBounded :: forall r s p. (KnownNat s, Bounded p, Integral p) => Bool -> String -> Either String (Decimal r s p)
- absDecimal :: KnownNat s => Decimal r s Integer -> Decimal r s Integer
- signumDecimal :: KnownNat s => Decimal r s Integer -> Decimal r s Integer
- plusDecimal :: Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer
- minusDecimal :: Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer
- timesDecimal :: Decimal r s1 Integer -> Decimal r s2 Integer -> Decimal r (s1 + s2) Integer
- timesDecimalWithoutLoss :: forall r s m. (KnownNat s, MonadThrow m) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer)
- timesDecimalWithRounding :: (KnownNat s, Round r Integer) => Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer
- divideDecimalWithoutLoss :: forall r s m. (KnownNat s, MonadThrow m) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer)
- divideDecimalWithRounding :: (MonadThrow m, KnownNat s, Round r Integer) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer)
- fromIntegerDecimal :: forall r s. KnownNat s => Integer -> Decimal r s Integer
- fromRationalDecimalWithoutLoss :: forall m r s. (MonadThrow m, KnownNat s) => Rational -> m (Decimal r s Integer)
- fromRationalDecimalWithRounding :: forall m r s. (MonadThrow m, KnownNat s, Round r Integer) => Rational -> m (Decimal r s Integer)
- toRationalDecimal :: (KnownNat s, Integral p) => Decimal r s p -> Rational
- absDecimalBounded :: (KnownNat s, MonadThrow m, Integral p, Bounded p) => Decimal r s p -> m (Decimal r s p)
- signumDecimalBounded :: (KnownNat s, MonadThrow m, Integral p, Bounded p) => Decimal r s p -> m (Decimal r s p)
- plusDecimalBounded :: (MonadThrow m, Eq p, Ord p, Num p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- minusDecimalBounded :: (MonadThrow m, Eq p, Ord p, Num p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- timesDecimalBounded :: (MonadThrow m, Integral p, Bounded p) => Decimal r s1 p -> Decimal r s2 p -> m (Decimal r (s1 + s2) p)
- timesDecimalBoundedWithoutLoss :: forall r s p m. (Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- timesDecimalBoundedWithRounding :: (MonadThrow m, KnownNat s, Round r Integer, Integral p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- divideDecimalBoundedWithoutLoss :: forall r s p m. (Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- divideDecimalBoundedWithRounding :: (MonadThrow m, KnownNat s, Round r Integer, Bounded p, Integral p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p)
- fromIntegralDecimalBounded :: (Integral p, Bounded p, KnownNat s, MonadThrow m) => p -> m (Decimal r s p)
- integralDecimalToDecimalBounded :: (Integral p', Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p' -> m (Decimal r s p)
- quotRemDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p) => Decimal r s p -> Integer -> m (Decimal r s p, Decimal r s p)
- fromIntegerDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p) => Decimal r s Integer -> m (Decimal r s p)
- fromIntegerDecimalBoundedIntegral :: forall m r s p. (MonadThrow m, Integral p, Bounded p, KnownNat s) => Integer -> m (Decimal r s p)
- fromRationalDecimalBoundedWithoutLoss :: (MonadThrow m, KnownNat s, Integral p, Bounded p) => Rational -> m (Decimal r s p)
- fromRationalDecimalBoundedWithRounding :: forall m r s p. (MonadThrow m, KnownNat s, Round r Integer, Bounded p, Integral p) => Rational -> m (Decimal r s p)
- bindM2Decimal :: Monad m => (p1 -> p2 -> m p) -> m (Decimal r1 s1 p1) -> m (Decimal r2 s2 p2) -> m (Decimal r s p)
- bindM2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
- class Monad m => MonadThrow (m :: Type -> Type) where
- data ArithException
- data SomeException
- arithD :: forall r s p. Arith (Decimal r s p) -> Arith (Decimal r s p)
- arithMD :: forall r s p m. MonadThrow m => Arith (Decimal r s p) -> m (Decimal r s p)
- arithMaybeD :: forall r s p. Arith (Decimal r s p) -> Maybe (Decimal r s p)
- arithEitherD :: forall r s p. Arith (Decimal r s p) -> Either SomeException (Decimal r s p)
- arithRoundD :: forall s' r s p k. (Round r p, KnownNat k, s ~ (s' + k)) => Arith (Decimal r s p) -> Arith (Decimal r s' p)
- data RoundHalfUp
- roundHalfUp :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundHalfDown
- roundHalfDown :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundHalfEven
- roundHalfEven :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundHalfToZero
- roundHalfToZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundHalfFromZero
- roundHalfFromZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundDown
- type Floor = RoundDown
- roundDown :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- data RoundToZero
- type Truncate = RoundToZero
- roundToZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
- decimalList :: Integral p => [p] -> [Decimal r s p]
- sumDecimalBounded :: (MonadThrow m, Foldable f, Eq p, Ord p, Num p, Bounded p) => f (Decimal r s p) -> m (Decimal r s p)
- productDecimalBoundedWithRounding :: (MonadThrow m, Foldable f, KnownNat s, Round r Integer, Integral p, Bounded p) => f (Decimal r s p) -> m (Decimal r s p)
- type family FixedScale e :: Nat
- toFixedDecimal :: (s ~ FixedScale e, Integral p) => Decimal r s p -> Fixed e
- fromFixedDecimal :: s ~ FixedScale e => Fixed e -> Decimal r s Integer
- fromFixedDecimalBounded :: (s ~ FixedScale e, MonadThrow m, Integral p, Bounded p) => Fixed e -> m (Decimal r s p)
- toScientificDecimal :: (Integral p, KnownNat s) => Decimal r s p -> Scientific
- fromScientificDecimal :: forall m r s. (MonadThrow m, KnownNat s) => Scientific -> m (Decimal r s Integer)
- fromScientificDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p, KnownNat s) => Scientific -> m (Decimal r s p)
Arithmetic
newtype Decimal r (s :: Nat) p Source #
Decimal number with custom precision (p
) and type level scaling (s
) parameter (i.e. number
of digits after the decimal point). As well as the rounding (r
) strategy to use.
Decimal p |
Instances
class Integral p => Round r p where Source #
Rounding strategy to be used with decimal numbers.
Since: 0.1.0
roundDecimal :: KnownNat k => Decimal r (n + k) p -> Decimal r n p Source #
Reduce the scale of a number by k
decimal places using rounding strategy r
Since: 0.1.0
Instances
wrapDecimal :: Integral p => p -> Decimal r s p Source #
unwrapDecimal :: Decimal r s p -> p Source #
Get out the underlying representation for the decimal number. No scaling will be done.
>>>
import Numeric.Decimal
>>>
unwrapDecimal (wrapDecimal 1234 :: Decimal RoundHalfUp 4 Int)
1234
Since: 0.1.0
splitDecimal :: (Integral p, KnownNat s) => Decimal r s p -> (p, p) Source #
Split the number at the decimal point, i.e. whole number and the fraction
>>>
import Numeric.Decimal
>>>
splitDecimal <$> (12.34 :: Arith (Decimal RoundHalfUp 2 Int))
Arith (12,34)
Since: 0.1.0
decimalNumerator :: Integral p => Decimal r s p -> Integer Source #
Get the numerator. Same as toInteger
. unwrapDecimal
>>>
import Numeric.Decimal
>>>
:set -XDataKinds -XTypeApplications
>>>
decimalNumerator <$> arithD @RoundHalfEven @3 @Int 123.45
Arith 123450
Since: 0.2.0
decimalDenominator :: KnownNat s => Decimal r s p -> Integer Source #
Get the decimal denominator. Always will be a multiple of 10
. Does not evaluate the
argument.
>>>
import Numeric.Decimal
>>>
:set -XDataKinds -XTypeApplications
>>>
decimalDenominator <$> arithD @RoundHalfEven @3 @Int 123.45
Arith 1000
Since: 0.2.0
getScale :: forall r s p. KnownNat s => Decimal r s p -> Integer Source #
Get the scale of a Decimal
. Argument is not evaluated.
>>>
import Numeric.Decimal
>>>
d <- arithM (36 :: Arith (Decimal RoundHalfUp 5 Int))
>>>
d
36.00000>>>
getScale d
5
Since: 0.1.0
scaleUp :: forall k r n. KnownNat k => Decimal r n Integer -> Decimal r (n + k) Integer Source #
Increase the precision of a Decimal
, use roundDecimal
if inverse is desired.
>>>
import Numeric.Decimal
>>>
d2 <- arithM (1.65 :: Arith (Decimal RoundHalfUp 2 Integer))
>>>
d2
1.65>>>
scaleUp d2 :: Decimal RoundHalfUp 50 Integer
1.65000000000000000000000000000000000000000000000000
Since: 0.2.0
scaleUpBounded :: forall k r n p m. (MonadThrow m, Integral p, Bounded p, KnownNat k) => Decimal r n p -> m (Decimal r (n + k) p) Source #
Increase the precision of a Decimal
backed by a bounded type, use roundDecimal
if
inverse is desired.
>>>
import Numeric.Decimal
>>>
d2 <- arithM (1.65 :: Arith (Decimal RoundHalfUp 2 Int16))
>>>
scaleUpBounded d2 :: IO (Decimal RoundHalfUp 3 Int16)
1.650>>>
scaleUpBounded d2 :: IO (Decimal RoundHalfUp 4 Int16)
1.6500>>>
scaleUpBounded d2 :: IO (Decimal RoundHalfUp 5 Int16)
*** Exception: arithmetic overflow
Since: 0.1.1
castRounding :: forall r' r s p. Decimal r s p -> Decimal r' s p Source #
Change the rounding strategy of a Decimal
>>>
import Numeric.Decimal
>>>
:set -XDataKinds -XTypeApplications
>>>
d <- arithMD @RoundHalfUp @3 @Int 123.45
>>>
roundDecimal d :: Decimal RoundHalfUp 1 Int
123.5>>>
:t castRounding @RoundDown d
castRounding @RoundDown d :: Decimal RoundDown 3 Int>>>
roundDecimal (castRounding d) :: Decimal RoundDown 1 Int
123.4
Since: 0.2.0
parseDecimalBounded :: forall r s p. (KnownNat s, Bounded p, Integral p) => Bool -> String -> Either String (Decimal r s p) Source #
Decimal Arithmetic
Integer
absDecimal :: KnownNat s => Decimal r s Integer -> Decimal r s Integer Source #
Compute absolute value of a decimal
Since: 0.2.0
signumDecimal :: KnownNat s => Decimal r s Integer -> Decimal r s Integer Source #
Compute signum of a decimal, always one of 1, 0 or -1
Since: 0.2.0
plusDecimal :: Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer Source #
Add two decimal numbers backed by Integer
.
Since: 0.1.0
minusDecimal :: Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer Source #
Subtract two decimal numbers backed by Integer
.
Since: 0.1.0
timesDecimal :: Decimal r s1 Integer -> Decimal r s2 Integer -> Decimal r (s1 + s2) Integer Source #
Multiply two bounded decimal numbers, adjusting their scale at the type level as well.
Since: 0.1.0
timesDecimalWithoutLoss :: forall r s m. (KnownNat s, MonadThrow m) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer) Source #
Multiply two decimal numbers that have the same scale, while throwing PrecisionLoss
whenever multiplication cannot be done without rounding.
Since: 0.2.0
timesDecimalWithRounding :: (KnownNat s, Round r Integer) => Decimal r s Integer -> Decimal r s Integer -> Decimal r s Integer Source #
Multiply two decimal numbers backed by Integer
, while rounding the result according
to the rounding strategy.
Since: 0.2.0
divideDecimalWithoutLoss :: forall r s m. (KnownNat s, MonadThrow m) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer) Source #
Divide two decimal numbers that have the same scale, while throwing PrecisionLoss
whenever division cannot be done without rounding.
Since: 0.2.0
divideDecimalWithRounding :: (MonadThrow m, KnownNat s, Round r Integer) => Decimal r s Integer -> Decimal r s Integer -> m (Decimal r s Integer) Source #
fromIntegerDecimal :: forall r s. KnownNat s => Integer -> Decimal r s Integer Source #
Convert an Integer
while performing the necessary scaling
>>>
import Numeric.Decimal
>>>
fromIntegerDecimal 1234 :: Decimal RoundHalfUp 4 Integer
1234.0000
Since: 0.2.0
fromRationalDecimalWithoutLoss :: forall m r s. (MonadThrow m, KnownNat s) => Rational -> m (Decimal r s Integer) Source #
Convert from Rational
to a Decimal
backed by Integer
. PrecisionLoss
will be
thrown if conversion cannot be achieved without any loss of data. In case that rounding
is acceptable use fromRationalDecimalBoundedWithRounding
Since: 0.2.0
fromRationalDecimalWithRounding :: forall m r s. (MonadThrow m, KnownNat s, Round r Integer) => Rational -> m (Decimal r s Integer) Source #
toRationalDecimal :: (KnownNat s, Integral p) => Decimal r s p -> Rational Source #
Convert a decimal to a Rational
Since: 0.2.0
Bounded Integral
absDecimalBounded :: (KnownNat s, MonadThrow m, Integral p, Bounded p) => Decimal r s p -> m (Decimal r s p) Source #
Compute absolute value of a bounded decimal. Protects against overflows for negative
minBound
.
>>>
abs (minBound :: Int8)
-128>>>
import Numeric.Decimal
>>>
d <- arithM (fromRational (-1.28) :: Arith (Decimal RoundHalfUp 2 Int8))
>>>
d
-1.28>>>
absDecimalBounded d :: Either SomeException (Decimal RoundHalfUp 2 Int8)
Left arithmetic overflow
Note - Watch out for order of negation
>>>
-1.28 :: Arith (Decimal RoundHalfUp 2 Int8)
ArithError arithmetic overflow>>>
negate (1.28 :: Arith (Decimal RoundHalfUp 2 Int8))
ArithError arithmetic overflow>>>
:set -XNegativeLiterals
>>>
-1.28 :: Arith (Decimal RoundHalfUp 2 Int8)
Arith -1.28
Since: 0.2.0
signumDecimalBounded :: (KnownNat s, MonadThrow m, Integral p, Bounded p) => Decimal r s p -> m (Decimal r s p) Source #
Compute signum of a decimal, always one of 1, 0 or -1
plusDecimalBounded :: (MonadThrow m, Eq p, Ord p, Num p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
Add two decimal numbers.
Since: 0.1.0
minusDecimalBounded :: (MonadThrow m, Eq p, Ord p, Num p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
Subtract two decimal numbers.
Since: 0.1.0
timesDecimalBounded :: (MonadThrow m, Integral p, Bounded p) => Decimal r s1 p -> Decimal r s2 p -> m (Decimal r (s1 + s2) p) Source #
Multiply two bounded decimal numbers, adjusting their scale at the type level as well.
Since: 0.1.0
timesDecimalBoundedWithoutLoss :: forall r s p m. (Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
timesDecimalBoundedWithRounding :: (MonadThrow m, KnownNat s, Round r Integer, Integral p, Bounded p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
Multiply two decimal numbers, while rounding the result according to the rounding strategy.
Since: 0.2.0
divideDecimalBoundedWithoutLoss :: forall r s p m. (Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
Divide two decimal numbers that have the same scale, while throwing PrecisionLoss
whenever division cannot be done without rounding.
Since: 0.2.0
divideDecimalBoundedWithRounding :: (MonadThrow m, KnownNat s, Round r Integer, Bounded p, Integral p) => Decimal r s p -> Decimal r s p -> m (Decimal r s p) Source #
fromIntegralDecimalBounded :: (Integral p, Bounded p, KnownNat s, MonadThrow m) => p -> m (Decimal r s p) Source #
Convert a bounded integeral into a decimal, while performing the necessary scaling
>>>
import Numeric.Decimal
>>>
fromIntegralDecimalBounded 1234 :: IO (Decimal RoundHalfUp 4 Int)
1234.0000>>>
fromIntegralDecimalBounded 1234 :: IO (Decimal RoundHalfUp 4 Int16)
*** Exception: arithmetic overflow
Since: 0.2.0
integralDecimalToDecimalBounded :: (Integral p', Integral p, Bounded p, KnownNat s, MonadThrow m) => Decimal r s p' -> m (Decimal r s p) Source #
Convert a decimal backed by an integral to another decimal backed by a bounded
integeral, while checking for Overflow
/Underflow
>>>
import Numeric.Decimal
>>>
fromIntegralDecimalBounded 1234 :: IO (Decimal RoundHalfUp 4 Int)
1234.0000>>>
fromIntegralDecimalBounded 1234 :: IO (Decimal RoundHalfUp 4 Int16)
*** Exception: arithmetic overflow
Since: 0.2.0
quotRemDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p) => Decimal r s p -> Integer -> m (Decimal r s p, Decimal r s p) Source #
fromIntegerDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p) => Decimal r s Integer -> m (Decimal r s p) Source #
fromIntegerDecimalBoundedIntegral :: forall m r s p. (MonadThrow m, Integral p, Bounded p, KnownNat s) => Integer -> m (Decimal r s p) Source #
Convert an Integer to a Decimal backed by a bounded integral while doing proper scaling and checking the bounds.
Since: 0.2.0
fromRationalDecimalBoundedWithoutLoss :: (MonadThrow m, KnownNat s, Integral p, Bounded p) => Rational -> m (Decimal r s p) Source #
fromRationalDecimalBoundedWithRounding :: forall m r s p. (MonadThrow m, KnownNat s, Round r Integer, Bounded p, Integral p) => Rational -> m (Decimal r s p) Source #
bindM2Decimal :: Monad m => (p1 -> p2 -> m p) -> m (Decimal r1 s1 p1) -> m (Decimal r2 s2 p2) -> m (Decimal r s p) Source #
Evaluation failure
class Monad m => MonadThrow (m :: Type -> Type) where #
A class for monads in which exceptions may be thrown.
Instances should obey the following law:
throwM e >> x = throwM e
In other words, throwing an exception short-circuits the rest of the monadic computation.
throwM :: Exception e => e -> m a #
Throw an exception. Note that this throws when this action is run in
the monad m
, not when it is applied. It is a generalization of
Control.Exception's throwIO
.
Should satisfy the law:
throwM e >> f = throwM e
Instances
data ArithException #
Arithmetic exceptions.
Overflow | |
Underflow | |
LossOfPrecision | |
DivideByZero | |
Denormal | |
RatioZeroDenominator | Since: base-4.6.0.0 |
Instances
Eq ArithException | Since: base-3.0 |
Defined in GHC.Exception.Type (==) :: ArithException -> ArithException -> Bool # (/=) :: ArithException -> ArithException -> Bool # | |
Ord ArithException | Since: base-3.0 |
Defined in GHC.Exception.Type compare :: ArithException -> ArithException -> Ordering # (<) :: ArithException -> ArithException -> Bool # (<=) :: ArithException -> ArithException -> Bool # (>) :: ArithException -> ArithException -> Bool # (>=) :: ArithException -> ArithException -> Bool # max :: ArithException -> ArithException -> ArithException # min :: ArithException -> ArithException -> ArithException # | |
Show ArithException | Since: base-4.0.0.0 |
Defined in GHC.Exception.Type showsPrec :: Int -> ArithException -> ShowS # show :: ArithException -> String # showList :: [ArithException] -> ShowS # | |
Exception ArithException | Since: base-4.0.0.0 |
Defined in GHC.Exception.Type |
data SomeException #
The SomeException
type is the root of the exception type hierarchy.
When an exception of type e
is thrown, behind the scenes it is
encapsulated in a SomeException
.
Instances
Show SomeException | Since: base-3.0 |
Defined in GHC.Exception.Type showsPrec :: Int -> SomeException -> ShowS # show :: SomeException -> String # showList :: [SomeException] -> ShowS # | |
Exception SomeException | Since: base-3.0 |
Defined in GHC.Exception.Type |
arithD :: forall r s p. Arith (Decimal r s p) -> Arith (Decimal r s p) Source #
A way to type restrict a polymorphic computation.
arithD
provide an easy way to use TypeApplications
to supply a type of Decimal:
>>>
import Numeric.Decimal
>>>
:set -XTypeApplications
>>>
arithM $ arithD @RoundDown @3 @Word (1.1 + 123)
124.100>>>
arithM $ arithD @RoundDown @3 @Word (1.1 - 123)
*** Exception: arithmetic underflow
Since: 0.2.0
arithMD :: forall r s p m. MonadThrow m => Arith (Decimal r s p) -> m (Decimal r s p) Source #
A way to type restrict a polymorphic computation.
arithD
provide an easy way to use TypeApplications
to supply a type of Decimal:
>>>
import Numeric.Decimal
>>>
:set -XDataKinds -XTypeApplications
>>>
arithMD @RoundDown @3 @Word (1.1 + 123)
124.100>>>
arithMD @RoundDown @3 @Word (1.1 - 123)
*** Exception: arithmetic underflow
Since: 0.2.0
arithEitherD :: forall r s p. Arith (Decimal r s p) -> Either SomeException (Decimal r s p) Source #
arithRoundD :: forall s' r s p k. (Round r p, KnownNat k, s ~ (s' + k)) => Arith (Decimal r s p) -> Arith (Decimal r s' p) Source #
A way to type restrict a polymorphic computation.
>>>
import Numeric.Decimal
>>>
arithRoundD @1 @RoundDown @2 @Word (123.05 + 1.1)
Arith 124.1
Since: 0.2.0
Rounding
Round half up
data RoundHalfUp Source #
Round half up rounding strategy:
>>>
:set -XDataKinds
>>>
roundDecimal <$> (3.740 :: Arith (Decimal RoundHalfUp 3 Int)) :: Arith (Decimal RoundHalfUp 1 Int)
Arith 3.7
Or with a bit more concise approach using arithRoundD
and TypeApplications
:
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundHalfUp @3 @Int 3.740
Arith 3.7>>>
arithRoundD @1 @RoundHalfUp @3 @Int 3.749
Arith 3.7>>>
arithRoundD @1 @RoundHalfUp @3 @Int 3.750
Arith 3.8>>>
arithRoundD @1 @RoundHalfUp @3 @Int 3.751
Arith 3.8>>>
arithRoundD @1 @RoundHalfUp @3 @Int 3.760
Arith 3.8>>>
arithRoundD @1 @RoundHalfUp @3 @Int (-3.740)
Arith -3.7>>>
arithRoundD @1 @RoundHalfUp @3 @Int (-3.749)
Arith -3.7>>>
arithRoundD @1 @RoundHalfUp @3 @Int (-3.750)
Arith -3.7>>>
arithRoundD @1 @RoundHalfUp @3 @Int (-3.751)
Arith -3.8>>>
arithRoundD @1 @RoundHalfUp @3 @Int (-3.760)
Arith -3.8
Since: 0.1.0
Instances
roundHalfUp :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round half down
data RoundHalfDown Source #
Round half down rounding strategy:
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundHalfDown @3 @Int 3.740
Arith 3.7>>>
arithRoundD @1 @RoundHalfDown @3 @Int 3.749
Arith 3.7>>>
arithRoundD @1 @RoundHalfDown @3 @Int 3.750
Arith 3.7>>>
arithRoundD @1 @RoundHalfDown @3 @Int 3.751
Arith 3.8>>>
arithRoundD @1 @RoundHalfDown @3 @Int 3.760
Arith 3.8>>>
arithRoundD @1 @RoundHalfDown @3 @Int (-3.740)
Arith -3.7>>>
arithRoundD @1 @RoundHalfDown @3 @Int (-3.749)
Arith -3.7>>>
arithRoundD @1 @RoundHalfDown @3 @Int (-3.750)
Arith -3.8>>>
arithRoundD @1 @RoundHalfDown @3 @Int (-3.751)
Arith -3.8>>>
arithRoundD @1 @RoundHalfDown @3 @Int (-3.760)
Arith -3.8
Since: 0.2.0
Instances
roundHalfDown :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round half even
data RoundHalfEven Source #
Round half even rounding
strategy. If the fractional part of x is 0.5, then y is the even integer nearest to
x. This is the default rounding strategy in Haskell implemented by round
.
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.650
Arith 3.6>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.740
Arith 3.7>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.749
Arith 3.7>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.750
Arith 3.8>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.751
Arith 3.8>>>
arithRoundD @1 @RoundHalfEven @3 @Int 3.760
Arith 3.8>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.650)
Arith -3.6>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.740)
Arith -3.7>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.749)
Arith -3.7>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.750)
Arith -3.8>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.751)
Arith -3.8>>>
arithRoundD @1 @RoundHalfEven @3 @Int (-3.760)
Arith -3.8
Since: 0.2.0
Instances
roundHalfEven :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round half to zero
data RoundHalfToZero Source #
Round half towards zero rounding strategy. If the fraction of x is exactly 0.5, then y = x − 0.5 if x is positive, and y = x + 0.5 if x is negative.
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundHalfToZero @3 @Int 3.650
Arith 3.6>>>
arithRoundD @1 @RoundHalfToZero @3 @Int 3.740
Arith 3.7>>>
arithRoundD @1 @RoundHalfToZero @4 @Int 3.7501
Arith 3.8>>>
arithRoundD @1 @RoundHalfToZero @3 @Int (-3.650)
Arith -3.6>>>
arithRoundD @1 @RoundHalfToZero @3 @Int (-3.740)
Arith -3.7>>>
arithRoundD @1 @RoundHalfToZero @4 @Int (-3.7501)
Arith -3.8>>>
arithRoundD @1 @RoundHalfToZero @3 @Int (-3.760)
Arith -3.8
Instances
roundHalfToZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round half from zero
data RoundHalfFromZero Source #
Round half away from zero rounding strategy. If the fraction of x is exactly 0.5, then y = x + 0.5 if x is positive, and y = x − 0.5 if x is negative.
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int 3.650
Arith 3.7>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int 3.740
Arith 3.7>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int 3.751
Arith 3.8>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int (-3.650)
Arith -3.7>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int (-3.740)
Arith -3.7>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int (-3.751)
Arith -3.8>>>
arithRoundD @1 @RoundHalfFromZero @3 @Int (-3.760)
Arith -3.8
Instances
roundHalfFromZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round down
Round down rounding
startegy. This the strategy that is implemented by floor
. Round towards minus
infinity:
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundDown @2 @Int 3.65
Arith 3.6>>>
arithRoundD @1 @RoundDown @2 @Int 3.75
Arith 3.7>>>
arithRoundD @1 @RoundDown @2 @Int 3.89
Arith 3.8>>>
arithRoundD @1 @RoundDown @2 @Int (-3.65)
Arith -3.7
Since: 0.2.0
Instances
roundDown :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Round towards zero
data RoundToZero Source #
Round towards zero strategy. Similar to Haskell's truncate
. Drop the fractional digits, regardless of
the sign.
>>>
:set -XDataKinds
>>>
:set -XTypeApplications
>>>
arithRoundD @1 @RoundToZero @2 @Int 3.65
Arith 3.6>>>
arithRoundD @1 @RoundToZero @2 @Int 3.75
Arith 3.7>>>
arithRoundD @1 @RoundToZero @2 @Int 3.89
Arith 3.8>>>
arithRoundD @1 @RoundToZero @2 @Int (-3.65)
Arith -3.6
Since: 0.2.0
Instances
type Truncate = RoundToZero Source #
Synonym for RoundToZero
Since: 0.1.0
roundToZero :: forall r n k p. (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p Source #
Operations
decimalList :: Integral p => [p] -> [Decimal r s p] Source #
O(1) - Conversion of a list.
Note: It doesn't do any scaling, eg:
>>>
:set -XDataKinds
>>>
import Numeric.Decimal
>>>
decimalList [1,20,300] :: [Decimal RoundHalfUp 2 Int]
[0.01,0.20,3.00]
If scaling is what you need use fromIntegral
instead:
>>>
sequenceA [1, 20, 300] :: Arith [Decimal RoundHalfUp 2 Int]
Arith [1.00,20.00,300.00]
Since: 0.1.0
sumDecimalBounded :: (MonadThrow m, Foldable f, Eq p, Ord p, Num p, Bounded p) => f (Decimal r s p) -> m (Decimal r s p) Source #
Sum a list of decimal numbers
>>>
:set -XDataKinds
>>>
sequenceA [1.1, 20.02, 300.003] >>= sumDecimalBounded :: Arith (Decimal RoundHalfUp 3 Int)
Arith 321.123
Since: 0.2.0
productDecimalBoundedWithRounding :: (MonadThrow m, Foldable f, KnownNat s, Round r Integer, Integral p, Bounded p) => f (Decimal r s p) -> m (Decimal r s p) Source #
Multiply all decimal numbers in the list while doing rounding.
>>>
:set -XDataKinds
>>>
product [1.1, 20.02, 300.003] :: Double
6606.666066000001>>>
xs <- arithM (mapM fromRational [1.1, 20.02, 300.003] :: Arith [Decimal RoundHalfUp 4 Int])
>>>
xs
[1.1000,20.0200,300.0030]>>>
productDecimalBoundedWithRounding xs
6606.6661
Since: 0.2.0
Conversion
Fixed
type family FixedScale e :: Nat Source #
Instances
type FixedScale E0 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E1 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E2 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E3 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E6 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E9 Source # | |
Defined in Numeric.Decimal | |
type FixedScale E12 Source # | |
Defined in Numeric.Decimal |
toFixedDecimal :: (s ~ FixedScale e, Integral p) => Decimal r s p -> Fixed e Source #
fromFixedDecimal :: s ~ FixedScale e => Fixed e -> Decimal r s Integer Source #
fromFixedDecimalBounded :: (s ~ FixedScale e, MonadThrow m, Integral p, Bounded p) => Fixed e -> m (Decimal r s p) Source #
Convert a Fixed
to a decimal backed by a bounded integral with the exactly same
precision
>>>
fromFixedDecimalBounded (123.458 :: Fixed E3) :: Arith (Decimal RoundToZero 3 Int)
Arith 123.458>>>
fromFixedDecimalBounded (123.458 :: Fixed E3) :: Arith (Decimal RoundToZero 3 Int8)
ArithError arithmetic overflow>>>
fromFixedDecimalBounded (-123.458 :: Fixed E3) :: Arith (Decimal RoundToZero 3 Word)
ArithError arithmetic underflow
Since: 0.2.0
Scientific
toScientificDecimal :: (Integral p, KnownNat s) => Decimal r s p -> Scientific Source #
Convert a Decimal
to Scientific
Since: 0.1.0
fromScientificDecimal :: forall m r s. (MonadThrow m, KnownNat s) => Scientific -> m (Decimal r s Integer) Source #
Convert Scientific to Decimal without loss of precision. Will return Left
Underflow
if
Scientific
has too many decimal places, more than Decimal
scaling is capable to handle.
Since: 0.1.0
fromScientificDecimalBounded :: forall m r s p. (MonadThrow m, Integral p, Bounded p, KnownNat s) => Scientific -> m (Decimal r s p) Source #
Convert from Scientific to bounded Decimal while checking for Overflow/Underflow
Since: 0.1.0