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


-- | A basic library for SI/binary prefix units
--   
--   This library deals with parsing values containing "prefix units" (both
--   binary and SI). For example, it can parse 10M and 1G, and it can also
--   format values for displaying with the "optimal" unit. For more
--   details, see the man page units(7),
--   <a>http://physics.nist.gov/cuu/Units/prefixes.html</a> and
--   <a>http://physics.nist.gov/cuu/Units/binary.html</a>.
@package prefix-units
@version 0.2.0


-- | Definitions and functions for parsing and formatting prefix units.
--   
--   This module defines the type <a>Unit</a> and associated functions for
--   parsing numbers containing a prefix unit (e.g. <tt>100M</tt>) into
--   corespondingly scaled values (for the above example,
--   <tt>100000000</tt>), and for formatting numbers.
--   
--   The units definition is taken from the man page <tt>units(7)</tt> and
--   the web sites <a>http://physics.nist.gov/cuu/Units/prefixes.html</a>
--   and <a>http://physics.nist.gov/cuu/Units/binary.html</a>.
--   
--   Since a give prefix unit (e.g. <tt>m</tt>) can be interpreted in
--   different ways, the module offers various ways to interpret this:
--   
--   <ul>
--   <li>in a binary context (e.g. when talking about memory), this will be
--   interpreted as 2^20 (see <a>ParseBinary</a>)</li>
--   <li>in a SI context dealing with multiples, this will be intepreted as
--   10^3 (see <a>ParseKMGT</a>)</li>
--   <li>in an exact parsing mode, this will be interpreded as the "milli"
--   prefix, i.e. 10^-3 (see <a>ParseExact</a>)</li>
--   </ul>
--   
--   The different parsing mode are offered as different contexts will have
--   different "natural" units, and always forcing precise parsing (which
--   also implies case-sensitivity) will lead to confusing user interfaces.
--   
--   The internal calculations when converting values are done via the
--   <a>Rational</a> type (with arbitrary precision), and precision loss
--   happens only at the last step of converting to the target type; for
--   float/doubles this is <a>fromRational</a>, for integral types this is
--   <a>round</a>.
--   
--   A few examples are given below:
--   
--   <pre>
--   &gt;&gt;&gt; showValue FormatBinary 2048
--   "2.0Ki"
--   
--   &gt;&gt;&gt; showValue FormatSiAll 0.0001
--   "100.0u"
--   
--   &gt;&gt;&gt; showValue (FormatFixed Mebi) 1048576
--   "1Mi"
--   
--   &gt;&gt;&gt; parseValue ParseExact "2.5Ki"::Either String Double
--   Right 2560.0
--   
--   &gt;&gt;&gt; parseValue ParseBinary "2M"::Either String Int
--   Right 2097152
--   
--   &gt;&gt;&gt; parseValue ParseExact "2ki"
--   Left "Unrecognised unit 'ki'"
--   </pre>
--   
--   The failure in the last example is due to the fact that
--   <a>ParseExact</a> is case-sensitive.
module Data.Prefix.Units

-- | The unit type.
data Unit
Yocto :: Unit
Zepto :: Unit
Atto :: Unit
Femto :: Unit
Pico :: Unit
Nano :: Unit
Micro :: Unit
Milli :: Unit
Centi :: Unit
Deci :: Unit
Deka :: Unit
Hecto :: Unit
Kilo :: Unit
Kibi :: Unit
Mega :: Unit
Mebi :: Unit
Giga :: Unit
Gibi :: Unit
Tera :: Unit
Tebi :: Unit
Peta :: Unit
Pebi :: Unit
Exa :: Unit
Exbi :: Unit
Zetta :: Unit
Yotta :: Unit

-- | Typeclass for handling values that can be converted to/from
--   <a>Rational</a>.
class (Real a) => RationalConvertible a

-- | Converts the value from Ratioal
convFromRational :: RationalConvertible a => Rational -> a

-- | List of all SI units.
siUnits :: [Unit]

-- | List of units which are supraunitary (their multiplier is greater than
--   one).
siSupraunitary :: [Unit]

-- | List of SI units which are greater or equal to <a>Kilo</a>.
siKMGT :: [Unit]

-- | List of binary units.
binaryUnits :: [Unit]

-- | The base for SI units.
siBase :: Rational

-- | The base for binary units.
binaryBase :: Rational

-- | Returns the unit scaling "multiplier" (which can be either supra- or
--   sub-unitary):
--   
--   <pre>
--   &gt;&gt;&gt; unitMultiplier Micro
--   1 % 1000000
--   
--   &gt;&gt;&gt; unitMultiplier Mebi
--   1048576 % 1
--   </pre>
unitMultiplier :: Unit -> Rational

-- | Returns the unit full name.
unitName :: Unit -> String

-- | Returns the unit ASCII symbol.
unitSymbol :: Unit -> String

-- | Returns the unit symbol, which for the <a>Micro</a> unit is not ASCII.
fancySymbol :: Unit -> String

-- | Defines the formatting modes.
data FormatMode

-- | Formats the value using any SI unit.
FormatSiAll :: FormatMode

-- | Formats the value using supraunitary SI units only (which means that
--   e.g. <tt>0.001</tt> will remain as such instead of being formatted as
--   <tt>1m</tt>).
FormatSiSupraunitary :: FormatMode

-- | Formats the value using units greater or equal to <a>Kilo</a>.
FormatSiKMGT :: FormatMode

-- | Formats the value using binary units.
FormatBinary :: FormatMode

-- | Formats the value as it is, without scaling.
FormatUnscaled :: FormatMode

-- | Formats the value using the given unit.
FormatFixed :: Unit -> FormatMode

-- | Computes the recommended unit for displaying a given value. The simple
--   algorithm uses the first unit for which we have a supraunitary
--   representation. In case we don't find any such value (e.g. for a zero
--   value), then <a>Nothing</a> is returned. For <a>FormatFixed</a>, we
--   always select the given unit, irrespective of the value.
recommendedUnit :: Real a => FormatMode -> a -> Maybe Unit

-- | Computes the scaled value and unit for a given value
formatValue :: RationalConvertible a => FormatMode -> a -> (a, Maybe Unit)

-- | Generates a final string representation of a value.
showValue :: (RationalConvertible a, Show a) => FormatMode -> a -> String

-- | Defines available parse modes.
data ParseMode

-- | Exact parser mode. This mode is fully case-sensitive.
ParseExact :: ParseMode

-- | Parses only units bigger than <a>Kilo</a>, respectively <a>Kibi</a>
--   (for binary units). This allows the parser to be case-insensitive.
ParseKMGT :: ParseMode

-- | Parses binary units only. In this mode, both the exact and shortened
--   forms are accepted (e.g. both "k" and "ki" will be converted into
--   <a>Kibi</a>). Furthermore, the parsing is case-insensitive.
ParseBinary :: ParseMode

-- | Parses a unit from a string. The exact parsing mode determines the
--   rules for parsing and the range of possible units.
parseSymbol :: ParseMode -> String -> Either String Unit

-- | Main parse routine.
parseValue :: (Read a, RationalConvertible a) => ParseMode -> String -> Either String a

-- | The available units range for various format modes.
unitRange :: FormatMode -> Either Unit [Unit]

-- | Defines unit handling mode on parse.
data ParseOptions

-- | Requires that the input string has a unit.
UnitRequired :: ParseOptions

-- | If unit is missing, use a default one.
UnitDefault :: Unit -> ParseOptions

-- | The unit is optional, a missing one means the value is not scaled.
UnitOptional :: ParseOptions

-- | Parses a symbol in the exact mode. See <a>ParseExact</a> for details.
parseExactSymbol :: String -> Either String Unit

-- | Parses a binary symbol. See <a>ParseBinary</a> for details.
parseBinarySymbol :: String -> Either String Unit

-- | Parses the given symbol as one of the "big" units (kilo/kibi and
--   above). This allows the parsing to be case-insensitive.
parseKMGTSymbol :: String -> Either String Unit

-- | Low-level parse routine. Takes two function arguments which fix the
--   initial and final conversion, a parse mode and the string to be
--   parsed.
parseGeneric :: (Read a, RationalConvertible a) => ParseOptions -> [Unit] -> ParseMode -> String -> Either String a

-- | Simple helper to generate the full string representation of an
--   integral value.
showValueWith :: (RationalConvertible a, Show a) => (Unit -> String) -> FormatMode -> a -> String
instance GHC.Show.Show Data.Prefix.Units.ParseOptions
instance GHC.Enum.Bounded Data.Prefix.Units.ParseMode
instance GHC.Enum.Enum Data.Prefix.Units.ParseMode
instance GHC.Show.Show Data.Prefix.Units.ParseMode
instance GHC.Show.Show Data.Prefix.Units.FormatMode
instance GHC.Classes.Ord Data.Prefix.Units.Unit
instance GHC.Enum.Bounded Data.Prefix.Units.Unit
instance GHC.Enum.Enum Data.Prefix.Units.Unit
instance GHC.Classes.Eq Data.Prefix.Units.Unit
instance GHC.Show.Show Data.Prefix.Units.Unit
instance Data.Prefix.Units.RationalConvertible GHC.Types.Int
instance Data.Prefix.Units.RationalConvertible GHC.Integer.Type.Integer
instance Data.Prefix.Units.RationalConvertible GHC.Types.Float
instance Data.Prefix.Units.RationalConvertible GHC.Types.Double
instance Data.Prefix.Units.RationalConvertible GHC.Real.Rational
