-- 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.4.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. Addition
--   and subtraction results have an exponent equal to the maximum of the
--   exponents of the arguments. Other operators have exponents sufficient
--   to show the exact result, up to a limit of 255:
--   
--   
--   0.15 * 0.15 :: Decimal    = 0.0225
--   (1/3) :: Decimal          = 0.33333333333333...
--   decimalPlaces (1/3)       = 255
--   
--   
--   While (/) is defined, you don't normally want to use it.
--   Instead The functions "divide" and "allocate" will split a decimal
--   amount into lists of results which 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 strongly recommended that Decimal be used,
--   with other types being used only where necessary (e.g. to conform to a
--   network protocol). For instance (1/3) :: DecimalRaw Int does
--   not give the right answer.
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.
--   
--   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 DecimalRaw i
Decimal :: !Word8 -> !i -> DecimalRaw i
[decimalPlaces] :: DecimalRaw i -> !Word8
[decimalMantissa] :: DecimalRaw i -> !i

-- | Arbitrary precision decimal type. 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 to another. Returns
--   Nothing if this would cause arithmetic overflow.
decimalConvert :: (Integral a, Integral b, Bounded b) => DecimalRaw a -> Maybe (DecimalRaw b)

-- | Convert a DecimalRaw from one base representation to another.
--   Does not check for overflow in the new representation. Only use after
--   using "roundTo" to put an upper value on the exponent, or to convert
--   to a larger representation.
unsafeDecimalConvert :: (Integral a, Integral b) => DecimalRaw a -> DecimalRaw b

-- | Round a DecimalRaw to a specified number of decimal places.
--   If the value ends in 5 then it is rounded away from zero.
roundTo :: (Integral i) => Word8 -> DecimalRaw i -> DecimalRaw i

-- | 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 :: Decimal -> Int -> [(Int, Decimal)]

-- | 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 :: Decimal -> [Integer] -> [Decimal]

-- | Try to convert Rational to Decimal with absolute precision return
--   string with fail description if not converted
eitherFromRational :: (Integral i) => Rational -> Either String (DecimalRaw i)

-- | Reduce the exponent of the decimal number to the minimal possible
--   value
normalizeDecimal :: (Integral i) => DecimalRaw i -> DecimalRaw i
instance Control.DeepSeq.NFData i => Control.DeepSeq.NFData (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Enum.Enum (Data.Decimal.DecimalRaw i)
instance (GHC.Real.Integral i, GHC.Show.Show i) => GHC.Show.Show (Data.Decimal.DecimalRaw i)
instance (GHC.Real.Integral i, GHC.Read.Read i) => GHC.Read.Read (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Classes.Eq (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Classes.Ord (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Num.Num (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.Real (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.Fractional (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.RealFrac (Data.Decimal.DecimalRaw i)
