-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Decimal numbers with variable precision -- -- A decimal number has an integer mantissa and a negative exponent. The -- exponent can be interpreted as the number of decimal places in the -- value. @package Decimal @version 0.2.2 -- | Decimal numbers are represented as m*10^(-e) where m -- and e are integers. The exponent e is an unsigned -- Word8. Hence the smallest value that can be represented is -- 10^-255. -- -- Unary arithmetic results have the exponent of the argument. Binary -- arithmetic results have an exponent equal to the maximum of the -- exponents of the arguments. -- -- Decimal numbers are defined as instances of Real. This means -- that conventional division is not defined. Instead the functions -- divide and allocate will split a decimal amount into -- lists of results. These results are guaranteed to sum to the original -- number. This is a useful property when doing financial arithmetic. -- -- The arithmetic on mantissas is always done using Integer, -- regardless of the type of DecimalRaw being manipulated. In -- practice it is recommended that Decimal be used, with other -- types being used only where necessary (e.g. to conform to a network -- protocol). module Data.Decimal -- | Raw decimal arithmetic type constructor. A decimal value consists of -- an integer mantissa and a negative exponent which is interpreted as -- the number of decimal places. The value stored in a Decimal d -- is therefore equal to: -- --
--   decimalMantissa d / (10 ^ decimalPlaces d)
--   
-- -- The Show instance will add trailing zeros, so show $ -- Decimal 3 1500 will return "1.500". Conversely the Read -- instance will use the decimal places to determine the precision. -- -- Arithmetic and comparision operators convert their arguments to the -- greater of the two precisions, and return a result of that precision. -- Regardless of the type of the arguments, all mantissa arithmetic is -- done using Integer types, so application developers do not -- need to worry about overflow in the internal algorithms. However the -- result of each operator will be converted to the mantissa type without -- checking for overflow. data Integral i => DecimalRaw i Decimal :: !Word8 -> !i -> DecimalRaw i decimalPlaces :: DecimalRaw i -> !Word8 decimalMantissa :: DecimalRaw i -> !i -- | Arbitrary precision decimal type. As a rule programs should do decimal -- arithmetic with this type and only convert to other instances of -- DecimalRaw where required by an external interface. -- -- Using this type is also faster because it avoids repeated conversions -- to and from Integer. type Decimal = DecimalRaw Integer -- | Convert a real fractional value into a Decimal of the appropriate -- precision. realFracToDecimal :: (Integral i, RealFrac r) => Word8 -> r -> DecimalRaw i -- | Convert a DecimalRaw from one base representation to another. -- Does not check for overflow in the new representation. decimalConvert :: (Integral a, Integral b) => DecimalRaw a -> DecimalRaw b -- | Round a DecimalRaw to a specified number of decimal places. roundTo :: Integral i => Word8 -> DecimalRaw i -> DecimalRaw Integer -- | Multiply a DecimalRaw by a RealFrac value. (*.) :: (Integral i, RealFrac r) => DecimalRaw i -> r -> DecimalRaw i -- | Divide a DecimalRaw value into one or more portions. The -- portions will be approximately equal, and the sum of the portions is -- guaranteed to be the original value. -- -- The portions are represented as a list of pairs. The first part of -- each pair is the number of portions, and the second part is the -- portion value. Hence 10 dollars divided 3 ways will produce [(2, -- 3.33), (1, 3.34)]. divide :: Integral i => DecimalRaw i -> Int -> [(Int, DecimalRaw i)] -- | Allocate a DecimalRaw value proportionately with the values -- in a list. The allocated portions are guaranteed to add up to the -- original value. -- -- Some of the allocations may be zero or negative, but the sum of the -- list must not be zero. The allocation is intended to be as close as -- possible to the following: -- --
--   let result = allocate d parts
--   in all (== d / sum parts) $ zipWith (/) result parts
--   
allocate :: Integral i => DecimalRaw i -> [Integer] -> [DecimalRaw i] -- | read is the inverse of show. -- --
--   read (show n) == n
--   
prop_readShow :: Decimal -> Bool -- | Read and show preserve decimal places. -- --
--   decimalPlaces (read (show n)) == decimalPlaces n
--   
prop_readShowPrecision :: Decimal -> Bool -- | fromInteger definition. -- --
--   decimalPlaces (fromInteger n) == 0 &&
--   decimalMantissa (fromInteger n) == n
--   
prop_fromIntegerZero :: Integer -> Bool -- | Increased precision does not affect equality. -- --
--   decimalPlaces d < maxBound ==> roundTo (decimalPlaces d + 1) d == d
--   
prop_increaseDecimals :: Decimal -> Property -- | Decreased precision can make two decimals equal, but it can never -- change their order. -- --
--   forAll d1, d2 :: Decimal -> legal beforeRound afterRound
--        where
--           beforeRound = compare d1 d2
--           afterRound = compare (roundTo 0 d1) (roundTo 0 d2)
--           legal GT x = x `elem` [GT, EQ]
--           legal EQ x = x `elem` [EQ]
--           legal LT x = x `elem` [LT, EQ]
--   
prop_decreaseDecimals :: Decimal -> Decimal -> Bool -- |
--   (x + y) - y == x
--   
prop_inverseAdd :: Decimal -> Decimal -> Bool -- | Multiplication is repeated addition. -- --
--   forall d, NonNegative i : (sum $ replicate i d) == d * fromIntegral (max i 0)
--   
prop_repeatedAdd :: Decimal -> Word8 -> Bool -- | Division produces the right number of parts. -- --
--   forall d, Positive i : (sum $ map fst $ divide d i) == i
--   
prop_divisionParts :: Decimal -> Positive Int -> Property -- | Division doesn't drop any units. -- --
--   forall d, Positive i : (sum $ map (\(n,d1) -> fromIntegral n * d1) $ divide d i) == d
--   
prop_divisionUnits :: Decimal -> Positive Int -> Bool -- | Allocate produces the right number of parts. -- --
--   sum ps /= 0  ==>  length ps == length (allocate d ps)
--   
prop_allocateParts :: Decimal -> [Integer] -> Property -- | Allocate doesn't drop any units. -- --
--   sum ps /= 0  ==>  sum (allocate d ps) == d
--   
prop_allocateUnits :: Decimal -> [Integer] -> Property -- | Absolute value definition -- --
--   decimalPlaces a == decimalPlaces d && 
--   decimalMantissa a == abs (decimalMantissa d)
--      where a = abs d
--   
prop_abs :: Decimal -> Bool -- | Sign number defintion -- --
--   signum d == (fromInteger $ signum $ decimalMantissa d)
--   
prop_signum :: Decimal -> Bool instance (Integral i, Arbitrary i) => CoArbitrary (DecimalRaw i) instance (Integral i, Arbitrary i) => Arbitrary (DecimalRaw i) instance Integral i => Real (DecimalRaw i) instance Integral i => Num (DecimalRaw i) instance Integral i => Ord (DecimalRaw i) instance Integral i => Eq (DecimalRaw i) instance (Integral i, Read i) => Read (DecimalRaw i) instance (Integral i, Show i) => Show (DecimalRaw i)