-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | 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.5.2


-- | Decimal numbers are represented as <tt>m*10^(-e)</tt> where <tt>m</tt>
--   and <tt>e</tt> are integers. The exponent <tt>e</tt> is an unsigned
--   Word8. Hence the smallest value that can be represented is
--   <tt>10^-255</tt>.
--   
--   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:
--   
--   <pre>
--   0.15 * 0.15 :: Decimal    = 0.0225
--   (1/3) :: Decimal          = 0.33333333333333...
--   decimalPlaces (1/3)       = 255
--   </pre>
--   
--   While <tt>(/)</tt> 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 <tt>Integer</tt>,
--   regardless of the type of <tt>DecimalRaw</tt> being manipulated. In
--   practice it is strongly recommended that <tt>Decimal</tt> be used,
--   with other types being used only where necessary (e.g. to conform to a
--   network protocol). For instance <tt>(1/3) :: DecimalRaw Int</tt> does
--   not give the right answer.
--   
--   Care must be taken with literal values of type Decimal. As per the
--   Haskell Report, the literal <tt>10.00</tt> will be converted into
--   <tt>fromRational 10.00</tt>, which in a <tt>Decimal</tt> context will
--   be converted into <tt>10</tt> with zero decimal places. Likewise
--   <tt>10.10</tt> will be converted into <tt>10.1</tt> with one decimal
--   place. If you mean <tt>10.00</tt> with 2 decimal places then you have
--   to write <tt>roundTo 2 10</tt>.
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 <tt>Decimal d</tt>
--   is therefore equal to:
--   
--   <pre>
--   decimalMantissa d / (10 ^ decimalPlaces d)
--   </pre>
--   
--   The <a>Show</a> instance will add trailing zeros, so <tt>show $
--   Decimal 3 1500</tt> will return "1.500". Conversely the <a>Read</a>
--   instance will use the decimal places to determine the precision.
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
--   <a>DecimalRaw</a> where required by an external interface. This will
--   avoid issues with integer overflows.
--   
--   Using this type is also faster because it avoids repeated conversions
--   to and from <tt>Integer</tt>.
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 <tt>DecimalRaw</tt> from one base to another. Returns
--   <tt>Nothing</tt> if this would cause arithmetic overflow.
decimalConvert :: (Integral a, Integral b, Bounded b) => DecimalRaw a -> Maybe (DecimalRaw b)

-- | Convert a <tt>DecimalRaw</tt> 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 <tt>DecimalRaw</tt> to a specified number of decimal places.
--   If the value ends in <tt>5</tt> then it is rounded to the nearest even
--   value (Banker's Rounding)
roundTo :: Integral i => Word8 -> DecimalRaw i -> DecimalRaw i

-- | Round a <tt>DecimalRaw</tt> to a specified number of decimal places
--   using the specified rounding function. Typically this will be one of
--   <tt>floor</tt>, <tt>ceiling</tt>, <tt>truncate</tt> or <tt>round</tt>.
--   Note that <tt>roundTo == roundTo' round</tt>
roundTo' :: Integral i => (Rational -> i) -> Word8 -> DecimalRaw i -> DecimalRaw i

-- | Multiply a <tt>DecimalRaw</tt> by a <tt>RealFrac</tt> value.
(*.) :: (Integral i, RealFrac r) => DecimalRaw i -> r -> DecimalRaw i

-- | Divide a <tt>DecimalRaw</tt> 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 <tt>[(2,
--   3.33), (1, 3.34)]</tt>.
divide :: Decimal -> Int -> [(Int, Decimal)]

-- | Allocate a <tt>DecimalRaw</tt> 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:
--   
--   <pre>
--   let result = allocate d parts
--   in all (== d / sum parts) $ zipWith (/) result parts
--   </pre>
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 GHC.Internal.Real.Integral i => GHC.Internal.Enum.Enum (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Classes.Eq (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Internal.Real.Fractional (Data.Decimal.DecimalRaw i)
instance Control.DeepSeq.NFData i => Control.DeepSeq.NFData (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Internal.Num.Num (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Classes.Ord (Data.Decimal.DecimalRaw i)
instance (GHC.Internal.Real.Integral i, GHC.Internal.Read.Read i) => GHC.Internal.Read.Read (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Internal.Real.Real (Data.Decimal.DecimalRaw i)
instance GHC.Internal.Real.Integral i => GHC.Internal.Real.RealFrac (Data.Decimal.DecimalRaw i)
instance (GHC.Internal.Real.Integral i, GHC.Internal.Show.Show i) => GHC.Internal.Show.Show (Data.Decimal.DecimalRaw i)
