Safe Haskell | None |
---|---|
Language | Haskell2010 |
Import this module qualified:
import qualified Data.Money as Money
- data Dense currency
- dense :: Rational -> Maybe (Dense currency)
- type Discrete currency unit = Discrete' currency (Scale currency unit)
- data Discrete' currency scale
- fromDiscrete :: GoodScale scale => Discrete' currency scale -> Dense currency
- round :: GoodScale scale => Dense currency -> (Discrete' currency scale, Maybe (Dense currency))
- ceiling :: GoodScale scale => Dense currency -> (Discrete' currency scale, Maybe (Dense currency))
- floor :: GoodScale scale => Dense currency -> (Discrete' currency scale, Maybe (Dense currency))
- truncate :: GoodScale scale => Dense currency -> (Discrete' currency scale, Maybe (Dense currency))
- type family Scale (currency :: Symbol) (unit :: Symbol) :: (Nat, Nat)
- type GoodScale scale = (CmpNat 0 (Fst scale) ~ LT, CmpNat 0 (Snd scale) ~ LT, KnownNat (Fst scale), KnownNat (Snd scale))
- scale :: forall proxy scale. GoodScale scale => proxy scale -> Rational
- data ExchangeRate src dst
- exchangeRate :: Rational -> Maybe (ExchangeRate src dst)
- fromExchangeRate :: ExchangeRate src dst -> Rational
- flipExchangeRate :: ExchangeRate a b -> ExchangeRate b a
- exchange :: ExchangeRate src dst -> Dense src -> Dense dst
- data DenseRep
- denseRep :: KnownSymbol currency => Dense currency -> DenseRep
- fromDenseRep :: forall currency. KnownSymbol currency => DenseRep -> Maybe (Dense currency)
- withDenseRep :: DenseRep -> (forall currency. KnownSymbol currency => Dense currency -> r) -> r
- data DiscreteRep
- discreteRep :: (KnownSymbol currency, GoodScale scale) => Discrete' currency scale -> DiscreteRep
- fromDiscreteRep :: forall currency scale. (KnownSymbol currency, GoodScale scale) => DiscreteRep -> Maybe (Discrete' currency scale)
- withDiscreteRep :: forall r. DiscreteRep -> (forall currency scale. (KnownSymbol currency, GoodScale scale) => Discrete' currency scale -> r) -> r
- data ExchangeRateRep
- exchangeRateRep :: (KnownSymbol src, KnownSymbol dst) => ExchangeRate src dst -> ExchangeRateRep
- fromExchangeRateRep :: forall src dst. (KnownSymbol src, KnownSymbol dst) => ExchangeRateRep -> Maybe (ExchangeRate src dst)
- withExchangeRateRep :: ExchangeRateRep -> (forall src dst. (KnownSymbol src, KnownSymbol dst) => ExchangeRate src dst -> r) -> r
Dense monetary values
Dense
represents a dense monetary value for currency
(usually a
ISO-4217 currency code, but not necessarily) as a rational number.
While monetary values associated with a particular currency are discrete, you
can still treat monetary values as dense while operating on them. For
example, the half of USD 3.41
is USD 1.705
, which is not an amount that
can't be represented as a number of USD cents (the smallest unit that can
represent USD amounts). Nevertheless, if you eventually multiply USD 1.705
by 4
, for example, you end up with USD 6.82
, which is again a value
representable as USD cents. In other words, Dense
monetary values
allow us to perform precise calculations deferring the conversion to a
Discrete
monetary values as much as posible. Once you are ready to
aproximate a Dense
value to a Discrete
value you can use one of
round
, floor
, ceiling
or truncate
. Otherwise, using toRational
you
can obtain a precise Rational
representation.
Construct Dense
monetary values using dense
, or
fromInteger
/ fromIntegral
if that suffices.
WARNING if you want to treat a dense monetary value as a Real number (for
example, to take the square root of that monetary value), then you are on
your own. We can only guarantee lossless manipulation of rational values, so
you will need to convert back and forth betwen the Rational
representation
for Dense
and your (likely lossy) representation for Real numbers.
Eq (Dense currency) Source # | |
Fractional (Dense currency) Source # | |
Num (Dense currency) Source # | |
Ord (Dense currency) Source # | |
KnownSymbol currency => Read (Dense currency) Source # | |
Real (Dense currency) Source # | |
KnownSymbol currency => Show (Dense currency) Source # | |
Generic (Dense currency) Source # | |
Hashable (Dense currency) Source # | |
KnownSymbol currency => ToJSON (Dense currency) Source # | Compatible with |
KnownSymbol currency => FromJSON (Dense currency) Source # | Compatible with |
KnownSymbol currency => Binary (Dense currency) Source # | Compatible with |
KnownSymbol currency => Serialize (Dense currency) Source # | Compatible with |
NFData (Dense currency) Source # | |
KnownSymbol currency => Store (Dense currency) Source # | Compatible with |
type Rep (Dense currency) Source # | |
Discrete monetary values
type Discrete currency unit = Discrete' currency (Scale currency unit) Source #
Discrete
represents a discrete monetary value for a currency
expresed
as an integer amount of a particular unit
. For example, with currency ~
"USD"
and unit ~ "cent"
you can represent United States Dollars to
their full extent.
currency
is usually a ISO-4217 currency code, but not necessarily.
Construct Discrete
values using fromInteger
.
For example, if you want to represent GBP 21.05
, where the smallest
represetable unit for a GBP (United Kingdom Pound) is the penny, and 100
pennies equal 1 GBP (i.e.,
), then you can
use:Scale
"GBP" ~ '(100, 1)
fromInteger
2105 :: Discrete "GBP" "penny"
Because 2015 / 100 == 20.15
.
data Discrete' currency scale Source #
Discrete'
represents a discrete monetary value for a currency
expresed
as an amount of scale
, which is a rational number expressed as (numerator,
denominator)
.
You'll be using Discrete
instead of Discrete'
most of the time, which
mentions the unit name (such as cent or centavo) instead of explicitely
mentioning the unit scale.
Enum (Discrete' currency scale) Source # | |
Eq (Discrete' currency scale) Source # | |
TypeError Constraint ((:$$:) ((:$$:) ((:<>:) ((:<>:) ((:<>:) (Text "The ") (ShowType (Symbol -> (Nat, Nat) -> *) Discrete')) (Text " type is deliberately not a ")) (ShowType (* -> Constraint) Fractional)) ((:<>:) ((:<>:) ((:<>:) (Text "instance. Convert the ") (ShowType (Symbol -> (Nat, Nat) -> *) Discrete')) (Text " value to a ")) (ShowType (Symbol -> *) Dense))) ((:<>:) ((:<>:) (Text "value and use the ") (ShowType (* -> Constraint) Fractional)) (Text " features on it instead."))) => Fractional (Discrete' currency scale) Source # | |
Integral (Discrete' currency scale) Source # | |
Num (Discrete' currency scale) Source # | |
Ord (Discrete' currency scale) Source # | |
(KnownSymbol currency, GoodScale scale) => Read (Discrete' currency scale) Source # | |
Real (Discrete' currency scale) Source # | |
(KnownSymbol currency, GoodScale scale) => Show (Discrete' currency scale) Source # | |
Generic (Discrete' currency scale) Source # | |
Hashable (Discrete' currency scale) Source # | |
(KnownSymbol currency, GoodScale scale) => ToJSON (Discrete' currency scale) Source # | Compatible with |
(KnownSymbol currency, GoodScale scale) => FromJSON (Discrete' currency scale) Source # | Compatible with |
(KnownSymbol currency, GoodScale scale) => Binary (Discrete' currency scale) Source # | Compatible with |
(KnownSymbol currency, GoodScale scale) => Serialize (Discrete' currency scale) Source # | Compatible with |
NFData (Discrete' currency scale) Source # | |
(KnownSymbol currency, GoodScale scale) => Store (Discrete' currency scale) Source # | Compatible with |
type Rep (Discrete' currency scale) Source # | |
Round a Dense
value x
to the nearest value fully representable in
its currency
's unit
Scale
, which might be x
itself.
If x
is already fully representable in its currency
's unit
Scale
,
then the following holds:
round
x == (x,Nothing
)
Otherwise, if the nearest value to x
that is fully representable in its
currency
's unit
Scale
is greater than x
, then the following holds:
round
==ceiling
Otherwise, the nearest value to x
that is fully representable in its
currency
's unit
Scale
is smaller than x
, and the following holds:
round
==floor
Proof that round
doesn't lose money:
x == caseround
x of (y,Nothing
) -> y (y,Just
z) -> y + z
Round a Dense
value x
to the nearest value fully representable in
its currency
's unit
Scale
which is greater than x
or equal to x
.
If x
is already fully representable in its currency
's unit
Scale
,
then the following holds:
ceiling
x == (x,Nothing
)
Otherwise, if x
is not representable in its currency
's unit
Scale
,
then the following holds:
ceiling
x == (y,Just
z)
x /= y
z < zero
Proof that ceiling
doesn't lose money:
x == caseceiling
x of (y,Nothing
) -> y (y,Just
z) -> y + z
Round a Dense
value x
to the nearest value fully representable in
its currency
's unit
Scale
which is smaller than x
or equal to x
.
If x
is already fully representable in its currency
's unit
Scale
,
then the following holds:
floor
x == (x,Nothing
)
Otherwise, if x
is not representable in its currency
's unit
Scale
,
then the following holds:
floor
x == (y,Just
z)
x /= y
z > zero
Proof that floor
doesn't lose money:
x == casefloor
x of (y,Nothing
) -> y (y,Just
z) -> y + z
Round a Dense
value x
to the nearest value between zero and
x
(inclusive) which is fully representable in its currency
's unit
Scale
.
If x
is already fully representable in its currency
's unit
Scale
,
then the following holds:
truncate
x == (x,Nothing
)
Otherwise, if x
is positive, then the following holds:
truncate
==floor
Otherwise, if x
is negative, the following holds:
truncate
==ceiling
Proof that truncate
doesn't lose money:
x == casetruncate
x of (y,Nothing
) -> y (y,Just
z) -> y + z
Currency scales
type family Scale (currency :: Symbol) (unit :: Symbol) :: (Nat, Nat) Source #
is a rational number (expressed as Scale
currency unit'(numerator,
denominator)
) indicating how many pieces of unit
fit in currency
.
currency
is usually a ISO-4217 currency code, but not necessarily.
The Scale
will determine how to convert a Dense
value into a
Discrete
value and vice-versa.
For example, there are 100 USD cents in 1 USD, so the scale for this relationship is:
type instance Scale
"USD" "cent" = '(100, 1)
As another example, there is 1 dollar in USD, so the scale for this relationship is:
type instance Scale
"USD" "dollar" = '(1, 1)
When using Discrete
values to represent money, it will be impossible to
represent an amount of currency
smaller than unit
. So, if you decide to
use Scale "USD" "dollar"
as your scale, you will not be able to
represent values such as USD 3.50 or USD 21.87, since they are not exact
multiples of a dollar.
If there exists a cannonical smallest unit
that can fully represent the
currency, then an instance
exists.Scale
currency currency
type instance Scale
"USD" "USD" = Scale "USD" "cent"
For some monetary values, such as precious metals, the smallest representable unit is not obvious, since you can continue to split the precious metal many times before it stops being a precious metal. Still, for practical purposes we can make a sane arbitrary choice of smallest unit. For example, the base unit for XAU (Gold) is the troy ounce, which is too big to be considered the smallest unit, but we can arbitrarily choose the milligrain as our smallest unit, which is about as heavy as a single grain of table salt and should be sufficiently precise for all monetary practical purposes. A /troy ounce equals 480000 milligrains/.
type instance Scale
"XAG" "milligrain" = '(480000, 1)
You can use other units such as milligrams for measuring XAU, for example. However, since the amount of milligrams in a troy ounce (31103.477) is not integral, we need to use rational number to express it.
type instance Scale
"XAU" "milligram" = '(31103477, 1000)
If you try to obtain the 'Scale of a currency
without an obvious smallest
representable unit
, like XAU, you will get a compile error.
type Scale "AED" "AED" Source # | |
type Scale "AED" "dirham" Source # | |
type Scale "AED" "fils" Source # | |
type Scale "AFN" "AFN" Source # | |
type Scale "AFN" "afghani" Source # | |
type Scale "AFN" "pul" Source # | |
type Scale "ALL" "ALL" Source # | |
type Scale "ALL" "lek" Source # | |
type Scale "ALL" "qindarke" Source # | |
type Scale "AMD" "AMD" Source # | |
type Scale "AMD" "dram" Source # | |
type Scale "AMD" "luma" Source # | |
type Scale "ANG" "ANG" Source # | |
type Scale "ANG" "cent" Source # | |
type Scale "ANG" "guilder" Source # | |
type Scale "AOA" "AOA" Source # | |
type Scale "AOA" "centimo" Source # | |
type Scale "AOA" "kwanza" Source # | |
type Scale "ARS" "ARS" Source # | |
type Scale "ARS" "centavo" Source # | |
type Scale "ARS" "peso" Source # | |
type Scale "AUD" "AUD" Source # | |
type Scale "AUD" "cent" Source # | |
type Scale "AUD" "dollar" Source # | |
type Scale "AWG" "AWG" Source # | |
type Scale "AWG" "cent" Source # | |
type Scale "AWG" "florin" Source # | |
type Scale "AZN" "AZN" Source # | |
type Scale "AZN" "manat" Source # | |
type Scale "AZN" "qapik" Source # | |
type Scale "BAM" "BAM" Source # | |
type Scale "BAM" "fening" Source # | |
type Scale "BAM" "mark" Source # | |
type Scale "BBD" "BBD" Source # | |
type Scale "BBD" "cent" Source # | |
type Scale "BBD" "dollar" Source # | |
type Scale "BDT" "BDT" Source # | |
type Scale "BDT" "paisa" Source # | |
type Scale "BDT" "taka" Source # | |
type Scale "BGN" "BGN" Source # | |
type Scale "BGN" "lev" Source # | |
type Scale "BGN" "stotinka" Source # | |
type Scale "BHD" "BHD" Source # | |
type Scale "BHD" "dinar" Source # | |
type Scale "BHD" "fils" Source # | |
type Scale "BIF" "BIF" Source # | |
type Scale "BIF" "centime" Source # | |
type Scale "BIF" "franc" Source # | |
type Scale "BMD" "BMD" Source # | |
type Scale "BMD" "cent" Source # | |
type Scale "BMD" "dollar" Source # | |
type Scale "BND" "BND" Source # | |
type Scale "BND" "dollar" Source # | |
type Scale "BND" "sen" Source # | |
type Scale "BOB" "BOB" Source # | |
type Scale "BOB" "boliviano" Source # | |
type Scale "BOB" "centavo" Source # | |
type Scale "BOV" "BOV" Source # | |
type Scale "BRL" "BRL" Source # | |
type Scale "BRL" "centavo" Source # | |
type Scale "BRL" "real" Source # | |
type Scale "BSD" "BSD" Source # | |
type Scale "BSD" "cent" Source # | |
type Scale "BSD" "dollar" Source # | |
type Scale "BTC" "BTC" Source # | |
type Scale "BTC" "bitcoin" Source # | |
type Scale "BTC" "satoshi" Source # | |
type Scale "BTN" "BTN" Source # | |
type Scale "BTN" "chetrum" Source # | |
type Scale "BTN" "ngultrum" Source # | |
type Scale "BWP" "BWP" Source # | |
type Scale "BWP" "pula" Source # | |
type Scale "BWP" "thebe" Source # | |
type Scale "BYN" "BYN" Source # | |
type Scale "BYR" "BYR" Source # | |
type Scale "BYR" "kapyeyka" Source # | |
type Scale "BYR" "ruble" Source # | |
type Scale "BZD" "BZD" Source # | |
type Scale "BZD" "cent" Source # | |
type Scale "BZD" "dollar" Source # | |
type Scale "CAD" "CAD" Source # | |
type Scale "CAD" "cent" Source # | |
type Scale "CAD" "dollar" Source # | |
type Scale "CDF" "CDF" Source # | |
type Scale "CDF" "centime" Source # | |
type Scale "CDF" "franc" Source # | |
type Scale "CHE" "CHE" Source # | |
type Scale "CHF" "CHF" Source # | |
type Scale "CHF" "franc" Source # | |
type Scale "CHF" "rappen" Source # | |
type Scale "CHW" "CHW" Source # | |
type Scale "CLF" "CLF" Source # | |
type Scale "CLP" "CLP" Source # | |
type Scale "CLP" "centavo" Source # | |
type Scale "CLP" "peso" Source # | |
type Scale "CNY" "CNY" Source # | |
type Scale "CNY" "fen" Source # | |
type Scale "CNY" "yuan" Source # | |
type Scale "COP" "COP" Source # | |
type Scale "COP" "centavo" Source # | |
type Scale "COP" "peso" Source # | |
type Scale "COU" "COU" Source # | |
type Scale "CRC" "CRC" Source # | |
type Scale "CRC" "centimo" Source # | |
type Scale "CRC" "colon" Source # | |
type Scale "CUC" "CUC" Source # | |
type Scale "CUC" "centavo" Source # | |
type Scale "CUC" "peso" Source # | |
type Scale "CUP" "CUP" Source # | |
type Scale "CUP" "centavo" Source # | |
type Scale "CUP" "peso" Source # | |
type Scale "CVE" "CVE" Source # | |
type Scale "CVE" "centavo" Source # | |
type Scale "CVE" "escudo" Source # | |
type Scale "CZK" "CZK" Source # | |
type Scale "CZK" "haler" Source # | |
type Scale "CZK" "koruna" Source # | |
type Scale "DJF" "DJF" Source # | |
type Scale "DJF" "centime" Source # | |
type Scale "DJF" "franc" Source # | |
type Scale "DKK" "DKK" Source # | |
type Scale "DKK" "krone" Source # | |
type Scale "DKK" "ore" Source # | |
type Scale "DOP" "DOP" Source # | |
type Scale "DOP" "centavo" Source # | |
type Scale "DOP" "peso" Source # | |
type Scale "DZD" "DZD" Source # | |
type Scale "DZD" "dinar" Source # | |
type Scale "DZD" "santeem" Source # | |
type Scale "EGP" "EGP" Source # | |
type Scale "EGP" "piastre" Source # | |
type Scale "EGP" "pound" Source # | |
type Scale "ERN" "ERN" Source # | |
type Scale "ERN" "cent" Source # | |
type Scale "ERN" "nafka" Source # | |
type Scale "ETB" "ETB" Source # | |
type Scale "ETB" "birr" Source # | |
type Scale "ETB" "santim" Source # | |
type Scale "ETH" "ETH" Source # | |
type Scale "ETH" "babbage" Source # | |
type Scale "ETH" "ether" Source # | |
type Scale "ETH" "finney" Source # | |
type Scale "ETH" "gwei" Source # | |
type Scale "ETH" "kwei" Source # | |
type Scale "ETH" "lovelace" Source # | |
type Scale "ETH" "microether" Source # | |
type Scale "ETH" "milliether" Source # | |
type Scale "ETH" "mwei" Source # | |
type Scale "ETH" "shannon" Source # | |
type Scale "ETH" "szabo" Source # | |
type Scale "ETH" "wei" Source # | |
type Scale "EUR" "EUR" Source # | |
type Scale "EUR" "cent" Source # | |
type Scale "EUR" "euro" Source # | |
type Scale "FJD" "FJD" Source # | |
type Scale "FKP" "FKP" Source # | |
type Scale "FKP" "penny" Source # | |
type Scale "FKP" "pound" Source # | |
type Scale "GBP" "GBP" Source # | |
type Scale "GBP" "penny" Source # | |
type Scale "GBP" "pound" Source # | |
type Scale "GEL" "GEL" Source # | |
type Scale "GEL" "lari" Source # | |
type Scale "GEL" "tetri" Source # | |
type Scale "GHS" "GHS" Source # | |
type Scale "GHS" "cedi" Source # | |
type Scale "GHS" "pesewa" Source # | |
type Scale "GIP" "GIP" Source # | |
type Scale "GIP" "penny" Source # | |
type Scale "GIP" "pound" Source # | |
type Scale "GMD" "GMD" Source # | |
type Scale "GMD" "butut" Source # | |
type Scale "GMD" "dalasi" Source # | |
type Scale "GNF" "GNF" Source # | |
type Scale "GNF" "centime" Source # | |
type Scale "GNF" "franc" Source # | |
type Scale "GTQ" "GTQ" Source # | |
type Scale "GTQ" "centavo" Source # | |
type Scale "GTQ" "quetzal" Source # | |
type Scale "GYD" "GYD" Source # | |
type Scale "GYD" "cent" Source # | |
type Scale "GYD" "dollar" Source # | |
type Scale "HKD" "HKD" Source # | |
type Scale "HKD" "cent" Source # | |
type Scale "HKD" "dollar" Source # | |
type Scale "HNL" "HNL" Source # | |
type Scale "HNL" "centavo" Source # | |
type Scale "HNL" "lempira" Source # | |
type Scale "HRK" "HRK" Source # | |
type Scale "HRK" "kuna" Source # | |
type Scale "HRK" "lipa" Source # | |
type Scale "HTG" "HTG" Source # | |
type Scale "HTG" "centime" Source # | |
type Scale "HTG" "gourde" Source # | |
type Scale "HUF" "HUF" Source # | |
type Scale "HUF" "filler" Source # | |
type Scale "HUF" "forint" Source # | |
type Scale "IDR" "IDR" Source # | |
type Scale "IDR" "rupiah" Source # | |
type Scale "IDR" "sen" Source # | |
type Scale "ILS" "ILS" Source # | |
type Scale "ILS" "agora" Source # | |
type Scale "ILS" "shekel" Source # | |
type Scale "INR" "INR" Source # | |
type Scale "INR" "paisa" Source # | |
type Scale "INR" "rupee" Source # | |
type Scale "IQD" "IQD" Source # | |
type Scale "IQD" "dinar" Source # | |
type Scale "IQD" "fils" Source # | |
type Scale "IRR" "IRR" Source # | |
type Scale "IRR" "dinar" Source # | |
type Scale "IRR" "rial" Source # | |
type Scale "ISK" "ISK" Source # | |
type Scale "ISK" "eyir" Source # | |
type Scale "ISK" "krona" Source # | |
type Scale "JMD" "JMD" Source # | |
type Scale "JMD" "cent" Source # | |
type Scale "JMD" "dollar" Source # | |
type Scale "JOD" "JOD" Source # | |
type Scale "JOD" "dinar" Source # | |
type Scale "JOD" "piastre" Source # | |
type Scale "JPY" "JPY" Source # | |
type Scale "JPY" "sen" Source # | |
type Scale "JPY" "yen" Source # | |
type Scale "KES" "KES" Source # | |
type Scale "KES" "cent" Source # | |
type Scale "KES" "shilling" Source # | |
type Scale "KGS" "KGS" Source # | |
type Scale "KGS" "som" Source # | |
type Scale "KGS" "tyiyn" Source # | |
type Scale "KHR" "KHR" Source # | |
type Scale "KHR" "riel" Source # | |
type Scale "KHR" "sen" Source # | |
type Scale "KMF" "KMF" Source # | |
type Scale "KMF" "centime" Source # | |
type Scale "KMF" "franc" Source # | |
type Scale "KPW" "KPW" Source # | |
type Scale "KPW" "chon" Source # | |
type Scale "KPW" "won" Source # | |
type Scale "KRW" "KRW" Source # | |
type Scale "KRW" "jeon" Source # | |
type Scale "KRW" "won" Source # | |
type Scale "KWD" "KWD" Source # | |
type Scale "KWD" "dinar" Source # | |
type Scale "KWD" "fils" Source # | |
type Scale "KYD" "KYD" Source # | |
type Scale "KYD" "cent" Source # | |
type Scale "KYD" "dollar" Source # | |
type Scale "KZT" "KZT" Source # | |
type Scale "KZT" "tenge" Source # | |
type Scale "KZT" "tiyin" Source # | |
type Scale "LAK" "LAK" Source # | |
type Scale "LAK" "att" Source # | |
type Scale "LAK" "kip" Source # | |
type Scale "LBP" "LBP" Source # | |
type Scale "LBP" "piastre" Source # | |
type Scale "LBP" "pound" Source # | |
type Scale "LKR" "LKR" Source # | |
type Scale "LKR" "cent" Source # | |
type Scale "LKR" "rupee" Source # | |
type Scale "LRD" "LRD" Source # | |
type Scale "LRD" "cent" Source # | |
type Scale "LRD" "dollar" Source # | |
type Scale "LSL" "LSL" Source # | |
type Scale "LSL" "loti" Source # | |
type Scale "LSL" "sente" Source # | |
type Scale "LYD" "LYD" Source # | |
type Scale "LYD" "dinar" Source # | |
type Scale "LYD" "dirham" Source # | |
type Scale "MAD" "MAD" Source # | |
type Scale "MAD" "centime" Source # | |
type Scale "MAD" "dirham" Source # | |
type Scale "MDL" "MDL" Source # | |
type Scale "MDL" "ban" Source # | |
type Scale "MDL" "leu" Source # | |
type Scale "MGA" "MGA" Source # | |
type Scale "MGA" "ariary" Source # | |
type Scale "MGA" "iraimbilanja" Source # | |
type Scale "MKD" "MKD" Source # | |
type Scale "MKD" "denar" Source # | |
type Scale "MKD" "deni" Source # | |
type Scale "MMK" "MMK" Source # | |
type Scale "MMK" "kyat" Source # | |
type Scale "MMK" "pya" Source # | |
type Scale "MNT" "MNT" Source # | |
type Scale "MNT" "mongo" Source # | |
type Scale "MNT" "tugrik" Source # | |
type Scale "MOP" "MOP" Source # | |
type Scale "MOP" "avo" Source # | |
type Scale "MOP" "pataca" Source # | |
type Scale "MRO" "MRO" Source # | |
type Scale "MRO" "khoums" Source # | |
type Scale "MRO" "ouguiya" Source # | |
type Scale "MUR" "MUR" Source # | |
type Scale "MUR" "cent" Source # | |
type Scale "MUR" "rupee" Source # | |
type Scale "MVR" "MVR" Source # | |
type Scale "MVR" "laari" Source # | |
type Scale "MVR" "rufiyaa" Source # | |
type Scale "MWK" "MWK" Source # | |
type Scale "MWK" "kwacha" Source # | |
type Scale "MWK" "tambala" Source # | |
type Scale "MXN" "MXN" Source # | |
type Scale "MXN" "centavo" Source # | |
type Scale "MXN" "peso" Source # | |
type Scale "MXV" "MXV" Source # | |
type Scale "MYR" "MYR" Source # | |
type Scale "MYR" "ringgit" Source # | |
type Scale "MYR" "sen" Source # | |
type Scale "MZN" "MZN" Source # | |
type Scale "MZN" "centavo" Source # | |
type Scale "MZN" "metical" Source # | |
type Scale "NAD" "NAD" Source # | |
type Scale "NAD" "cent" Source # | |
type Scale "NAD" "dollar" Source # | |
type Scale "NGN" "NGN" Source # | |
type Scale "NGN" "kobo" Source # | |
type Scale "NGN" "naira" Source # | |
type Scale "NIO" "NIO" Source # | |
type Scale "NIO" "centavo" Source # | |
type Scale "NIO" "cordoba" Source # | |
type Scale "NOK" "NOK" Source # | |
type Scale "NOK" "krone" Source # | |
type Scale "NOK" "ore" Source # | |
type Scale "NPR" "NPR" Source # | |
type Scale "NPR" "paisa" Source # | |
type Scale "NPR" "rupee" Source # | |
type Scale "NZD" "NZD" Source # | |
type Scale "NZD" "cent" Source # | |
type Scale "NZD" "dollar" Source # | |
type Scale "OMR" "OMR" Source # | |
type Scale "OMR" "baisa" Source # | |
type Scale "OMR" "rial" Source # | |
type Scale "PAB" "PAB" Source # | |
type Scale "PAB" "balboa" Source # | |
type Scale "PAB" "centesimo" Source # | |
type Scale "PEN" "PEN" Source # | |
type Scale "PEN" "centimo" Source # | |
type Scale "PEN" "sol" Source # | |
type Scale "PGK" "PGK" Source # | |
type Scale "PGK" "kina" Source # | |
type Scale "PGK" "toea" Source # | |
type Scale "PHP" "PHP" Source # | |
type Scale "PHP" "centavo" Source # | |
type Scale "PHP" "peso" Source # | |
type Scale "PKR" "PKR" Source # | |
type Scale "PKR" "paisa" Source # | |
type Scale "PKR" "rupee" Source # | |
type Scale "PLN" "PLN" Source # | |
type Scale "PLN" "grosz" Source # | |
type Scale "PLN" "zloty" Source # | |
type Scale "PYG" "PYG" Source # | |
type Scale "PYG" "centimo" Source # | |
type Scale "PYG" "guarani" Source # | |
type Scale "QAR" "QAR" Source # | |
type Scale "QAR" "dirham" Source # | |
type Scale "QAR" "riyal" Source # | |
type Scale "RON" "RON" Source # | |
type Scale "RON" "ban" Source # | |
type Scale "RON" "leu" Source # | |
type Scale "RSD" "RSD" Source # | |
type Scale "RSD" "dinar" Source # | |
type Scale "RSD" "para" Source # | |
type Scale "RUB" "RUB" Source # | |
type Scale "RUB" "kopek" Source # | |
type Scale "RUB" "ruble" Source # | |
type Scale "RWF" "RWF" Source # | |
type Scale "RWF" "centime" Source # | |
type Scale "RWF" "franc" Source # | |
type Scale "SAR" "SAR" Source # | |
type Scale "SAR" "halala" Source # | |
type Scale "SAR" "riyal" Source # | |
type Scale "SBD" "SBD" Source # | |
type Scale "SBD" "cent" Source # | |
type Scale "SBD" "dollar" Source # | |
type Scale "SCR" "SCR" Source # | |
type Scale "SCR" "cent" Source # | |
type Scale "SCR" "rupee" Source # | |
type Scale "SDG" "SDG" Source # | |
type Scale "SDG" "piastre" Source # | |
type Scale "SDG" "pound" Source # | |
type Scale "SEK" "SEK" Source # | |
type Scale "SEK" "krona" Source # | |
type Scale "SEK" "ore" Source # | |
type Scale "SGD" "SGD" Source # | |
type Scale "SGD" "cent" Source # | |
type Scale "SGD" "dollar" Source # | |
type Scale "SHP" "SHP" Source # | |
type Scale "SHP" "penny" Source # | |
type Scale "SHP" "pound" Source # | |
type Scale "SLL" "SLL" Source # | |
type Scale "SLL" "cent" Source # | |
type Scale "SLL" "leone" Source # | |
type Scale "SOS" "SOS" Source # | |
type Scale "SOS" "cent" Source # | |
type Scale "SOS" "shilling" Source # | |
type Scale "SRD" "SRD" Source # | |
type Scale "SRD" "cent" Source # | |
type Scale "SRD" "dollar" Source # | |
type Scale "SSP" "SSP" Source # | |
type Scale "SSP" "piastre" Source # | |
type Scale "SSP" "pound" Source # | |
type Scale "STD" "STD" Source # | |
type Scale "STD" "centimo" Source # | |
type Scale "STD" "dobra" Source # | |
type Scale "SVC" "SVC" Source # | |
type Scale "SVC" "centavo" Source # | |
type Scale "SVC" "colon" Source # | |
type Scale "SYP" "SYP" Source # | |
type Scale "SYP" "piastre" Source # | |
type Scale "SYP" "pound" Source # | |
type Scale "SZL" "SZL" Source # | |
type Scale "SZL" "cent" Source # | |
type Scale "SZL" "lilangeni" Source # | |
type Scale "THB" "THB" Source # | |
type Scale "THB" "baht" Source # | |
type Scale "THB" "satang" Source # | |
type Scale "TJS" "TJS" Source # | |
type Scale "TJS" "diram" Source # | |
type Scale "TJS" "somoni" Source # | |
type Scale "TMT" "TMT" Source # | |
type Scale "TMT" "manat" Source # | |
type Scale "TMT" "tennesi" Source # | |
type Scale "TND" "TND" Source # | |
type Scale "TND" "dinar" Source # | |
type Scale "TND" "millime" Source # | |
type Scale "TOP" "TOP" Source # | |
type Scale "TOP" "pa'anga" Source # | |
type Scale "TOP" "seniti" Source # | |
type Scale "TRY" "TRY" Source # | |
type Scale "TRY" "kurus" Source # | |
type Scale "TRY" "lira" Source # | |
type Scale "TTD" "TTD" Source # | |
type Scale "TTD" "cent" Source # | |
type Scale "TTD" "dollar" Source # | |
type Scale "TWD" "TWD" Source # | |
type Scale "TWD" "cent" Source # | |
type Scale "TWD" "dollar" Source # | |
type Scale "TZS" "TZS" Source # | |
type Scale "TZS" "cent" Source # | |
type Scale "TZS" "shilling" Source # | |
type Scale "UAH" "UAH" Source # | |
type Scale "UAH" "hryvnia" Source # | |
type Scale "UAH" "kopiyka" Source # | |
type Scale "UGX" "UGX" Source # | |
type Scale "UGX" "cent" Source # | |
type Scale "UGX" "shilling" Source # | |
type Scale "USD" "USD" Source # | |
type Scale "USD" "cent" Source # | |
type Scale "USD" "dollar" Source # | |
type Scale "USN" "USN" Source # | |
type Scale "UYI" "UYI" Source # | |
type Scale "UYU" "UYU" Source # | |
type Scale "UYU" "centesimo" Source # | |
type Scale "UYU" "peso" Source # | |
type Scale "UZS" "UZS" Source # | |
type Scale "UZS" "som" Source # | |
type Scale "UZS" "tiyin" Source # | |
type Scale "VEF" "VEF" Source # | |
type Scale "VEF" "bolivar" Source # | |
type Scale "VEF" "centimo" Source # | |
type Scale "VND" "VND" Source # | |
type Scale "VND" "dong" Source # | |
type Scale "VND" "hao" Source # | |
type Scale "VUV" "VUV" Source # | |
type Scale "VUV" "vatu" Source # | |
type Scale "WST" "WST" Source # | |
type Scale "WST" "sene" Source # | |
type Scale "WST" "tala" Source # | |
type Scale "XAF" "XAF" Source # | |
type Scale "XAF" "centime" Source # | |
type Scale "XAF" "franc" Source # | |
type Scale "XAG" "XAG" Source # | |
type Scale "XAG" "grain" Source # | |
type Scale "XAG" "gram" Source # | |
type Scale "XAG" "kilogram" Source # | |
type Scale "XAG" "micrograin" Source # | |
type Scale "XAG" "microgram" Source # | |
type Scale "XAG" "milligrain" Source # | |
type Scale "XAG" "milligram" Source # | |
type Scale "XAG" "troy-ounce" Source # | |
type Scale "XAU" "XAU" Source # | |
type Scale "XAU" "grain" Source # | |
type Scale "XAU" "gram" Source # | |
type Scale "XAU" "kilogram" Source # | |
type Scale "XAU" "micrograin" Source # | |
type Scale "XAU" "microgram" Source # | |
type Scale "XAU" "milligrain" Source # | |
type Scale "XAU" "milligram" Source # | |
type Scale "XAU" "troy-ounce" Source # | |
type Scale "XBT" "XBT" Source # | |
type Scale "XBT" "bitcoin" Source # | |
type Scale "XBT" "satoshi" Source # | |
type Scale "XCD" "XCD" Source # | |
type Scale "XCD" "cent" Source # | |
type Scale "XCD" "dollar" Source # | |
type Scale "XDR" "XDR" Source # | |
type Scale "XOF" "XOF" Source # | |
type Scale "XOF" "centime" Source # | |
type Scale "XOF" "franc" Source # | |
type Scale "XPD" "XPD" Source # | |
type Scale "XPD" "grain" Source # | |
type Scale "XPD" "gram" Source # | |
type Scale "XPD" "kilogram" Source # | |
type Scale "XPD" "micrograin" Source # | |
type Scale "XPD" "microgram" Source # | |
type Scale "XPD" "milligrain" Source # | |
type Scale "XPD" "milligram" Source # | |
type Scale "XPD" "troy-ounce" Source # | |
type Scale "XPF" "XPF" Source # | |
type Scale "XPF" "centime" Source # | |
type Scale "XPF" "franc" Source # | |
type Scale "XPT" "XPT" Source # | |
type Scale "XPT" "grain" Source # | |
type Scale "XPT" "gram" Source # | |
type Scale "XPT" "kilogram" Source # | |
type Scale "XPT" "micrograin" Source # | |
type Scale "XPT" "microgram" Source # | |
type Scale "XPT" "milligrain" Source # | |
type Scale "XPT" "milligram" Source # | |
type Scale "XPT" "troy-ounce" Source # | |
type Scale "XSU" "XSU" Source # | |
type Scale "XUA" "XUA" Source # | |
type Scale "YER" "YER" Source # | |
type Scale "YER" "fils" Source # | |
type Scale "YER" "rial" Source # | |
type Scale "ZAR" "ZAR" Source # | |
type Scale "ZAR" "cent" Source # | |
type Scale "ZAR" "rand" Source # | |
type Scale "ZMW" "ZMW" Source # | |
type Scale "ZMW" "kwacha" Source # | |
type Scale "ZMW" "ngwee" Source # | |
type Scale "ZWL" "ZWL" Source # | |
type Scale "ZWL" "cent" Source # | |
type Scale "ZWL" "dollar" Source # | |
type GoodScale scale = (CmpNat 0 (Fst scale) ~ LT, CmpNat 0 (Snd scale) ~ LT, KnownNat (Fst scale), KnownNat (Snd scale)) Source #
Currency exchange
data ExchangeRate src dst Source #
Exchange rate for converting monetary values of currency src
into
monetary values of currency dst
by multiplying for it.
For example, if in order to convert USD to GBP we have to multiply by 1.2345, then we can represent this situaion using:
exchangeRate
(12345 % 10000) ::Maybe
(ExchangeRate
"USD" "GBP")
Eq (ExchangeRate src dst) Source # | |
Ord (ExchangeRate src dst) Source # | |
(KnownSymbol src, KnownSymbol dst) => Read (ExchangeRate src dst) Source # | |
(KnownSymbol src, KnownSymbol dst) => Show (ExchangeRate src dst) Source # | |
Generic (ExchangeRate src dst) Source # | |
Hashable (ExchangeRate src dst) Source # | |
(KnownSymbol src, KnownSymbol dst) => ToJSON (ExchangeRate src dst) Source # | Compatible with |
(KnownSymbol src, KnownSymbol dst) => FromJSON (ExchangeRate src dst) Source # | Compatible with |
(KnownSymbol src, KnownSymbol dst) => Binary (ExchangeRate src dst) Source # | Compatible with |
(KnownSymbol src, KnownSymbol dst) => Serialize (ExchangeRate src dst) Source # | Compatible with |
NFData (ExchangeRate src dst) Source # | |
(KnownSymbol src, KnownSymbol dst) => Store (ExchangeRate src dst) Source # | Compatible with |
type Rep (ExchangeRate src dst) Source # | |
exchangeRate :: Rational -> Maybe (ExchangeRate src dst) Source #
Safely construct an ExchangeRate
from a Rational
number.
For construction to succeed, this Rational
must be greater than 0,
different from infinity
and different from notANumber
.
fromExchangeRate :: ExchangeRate src dst -> Rational Source #
Obtain a Rational
representation of the ExchangeRate
.
This Rational
is statically guaranteed to be greater than 0, different
from infinity
and different from notANumber
.
flipExchangeRate :: ExchangeRate a b -> ExchangeRate b a Source #
exchange :: ExchangeRate src dst -> Dense src -> Dense dst Source #
Apply the ExchangeRate
to the given
monetary value.Dense
src
Identity law:
exchange
(flipExchangeRate
x) .exchange
x ==id
Use the Identity law for reasoning about going back and forth between src
and dst
in order to manage any leftovers that might not be representable as
a Discrete
monetary value of src
.
Serializable representations
A monomorphic representation of Dense
that is easier to serialize and
deserialize than Dense
in case you don't know the type indexes involved.
Eq DenseRep Source # | |
Ord DenseRep Source # | |
Show DenseRep Source # | |
Generic DenseRep Source # | |
Hashable DenseRep Source # | |
ToJSON DenseRep Source # | Compatible with |
FromJSON DenseRep Source # | Compatible with |
Binary DenseRep Source # | Compatible with |
Serialize DenseRep Source # | Compatible with |
NFData DenseRep Source # | |
Store DenseRep Source # | Compatible with |
type Rep DenseRep Source # | |
:: KnownSymbol currency | |
=> DenseRep | |
-> Maybe (Dense currency) |
:: DenseRep | |
-> (forall currency. KnownSymbol currency => Dense currency -> r) | |
-> r |
Convert a DenseRep
to a Dense
without knowing the target currency
.
Notice that currency
here can't leave its intended scope unless you can
prove equality with some other type at the outer scope, but in that case you
would be better off using fromDenseRep
directly.
data DiscreteRep Source #
A monomorphic representation of Discrete
that is easier to serialize and
deserialize than Discrete
in case you don't know the type indexes involved.
Eq DiscreteRep Source # | |
Ord DiscreteRep Source # | |
Show DiscreteRep Source # | |
Generic DiscreteRep Source # | |
Hashable DiscreteRep Source # | |
ToJSON DiscreteRep Source # | Compatible with |
FromJSON DiscreteRep Source # | Compatible with |
Binary DiscreteRep Source # | Compatible with |
Serialize DiscreteRep Source # | Compatible with |
NFData DiscreteRep Source # | |
Store DiscreteRep Source # | Compatible with |
type Rep DiscreteRep Source # | |
:: (KnownSymbol currency, GoodScale scale) | |
=> Discrete' currency scale | |
-> DiscreteRep |
Convert a Discrete
to a DiscreteRep
for ease of serialization.
:: (KnownSymbol currency, GoodScale scale) | |
=> DiscreteRep | |
-> Maybe (Discrete' currency scale) |
Attempt to convert a DiscreteRep
to a Discrete
, provided you know the
target currency
and unit
.
:: DiscreteRep | |
-> (forall currency scale. (KnownSymbol currency, GoodScale scale) => Discrete' currency scale -> r) | |
-> r |
Convert a DiscreteRep
to a Discrete
without knowing the target
currency
and unit
.
Notice that currency
and unit
here can't leave its intended scope unless
you can prove equality with some other type at the outer scope, but in that
case you would be better off using fromDiscreteRep
directly.
Notice that you may need to add an explicit type to the result of this function in order to keep the compiler happy.
data ExchangeRateRep Source #
A monomorphic representation of ExchangeRate
that is easier to serialize
and deserialize than ExchangeRate
in case you don't know the type indexes
involved.
Eq ExchangeRateRep Source # | |
Ord ExchangeRateRep Source # | |
Show ExchangeRateRep Source # | |
Generic ExchangeRateRep Source # | |
Hashable ExchangeRateRep Source # | |
ToJSON ExchangeRateRep Source # | Compatible with |
FromJSON ExchangeRateRep Source # | Compatible with |
Binary ExchangeRateRep Source # | Compatible with |
Serialize ExchangeRateRep Source # | Compatible with |
NFData ExchangeRateRep Source # | |
Store ExchangeRateRep Source # | Compatible with |
type Rep ExchangeRateRep Source # | |
:: (KnownSymbol src, KnownSymbol dst) | |
=> ExchangeRate src dst | |
-> ExchangeRateRep |
Convert a ExchangeRate
to a DiscreteRep
for ease of serialization.
:: (KnownSymbol src, KnownSymbol dst) | |
=> ExchangeRateRep | |
-> Maybe (ExchangeRate src dst) |
Attempt to convert a ExchangeRateRep
to a ExchangeRate
, provided you
know the target src
and dst
types.
:: ExchangeRateRep | |
-> (forall src dst. (KnownSymbol src, KnownSymbol dst) => ExchangeRate src dst -> r) | |
-> r |
Convert a ExchangeRateRep
to a ExchangeRate
without knowing the target
currency
and unit
.
Notice that src
and dst
here can't leave its intended scope unless
you can prove equality with some other type at the outer scope, but in that
case you would be better off using fromExchangeRateRep
directly.