From 2afff70b421aceee3c51440ff9c71ef783b490e3 Mon Sep 17 00:00:00 2001 From: Geoffrey Borough Date: Fri, 26 Apr 2024 15:59:30 +1000 Subject: [PATCH] fix yojson derive (#6) --- .ocamlformat | 7 +- CHANGES | 10 + README.md | 43 +- dune-project | 3 +- lib/discrete.ml | 95 +- lib/discrete.mli | 52 +- lib/dune | 6 +- lib/exchange.ml | 46 +- lib/exchange.mli | 26 +- lib/ops.ml | 228 +++ lib/ops.mli | 125 ++ lib/predefined.ml | 3776 +++++++++++++++++++++++---------------------- lib/quotient.ml | 58 +- lib/quotient.mli | 33 +- lib/qv.ml | 56 +- lib/qv_intf.ml | 48 +- lib/safemoney.ml | 65 +- lib/safemoney.mli | 17 + lib/types.ml | 65 + lib/utils.ml | 284 ---- lib/zv.ml | 17 +- lib/zv_intf.ml | 26 +- safemoney.opam | 10 +- test/dune | 16 +- test/test.ml | 122 +- 25 files changed, 2679 insertions(+), 2555 deletions(-) create mode 100644 lib/ops.ml create mode 100644 lib/ops.mli create mode 100644 lib/safemoney.mli create mode 100644 lib/types.ml delete mode 100644 lib/utils.ml diff --git a/.ocamlformat b/.ocamlformat index aa5495a..982c797 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,2 +1,5 @@ -profile = janestreet -version = 0.26.1 \ No newline at end of file +profile = ocamlformat +break-cases = fit +margin = 77 +wrap-comments = true +line-endings = lf \ No newline at end of file diff --git a/CHANGES b/CHANGES index e862bd1..1a2f1c3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +## 0.2.0 (2024-04-26) + +* Removed transitive dependecies +* Removed unnecessary sexp derive +* Fixed Yojson derive on exceptions +* Fixed module scopes and exports +* Renamed library public name to Safemoney +* Renamed module Utils to Ops and added signatures +* Updated code examples + ## 0.1.1 (2023-09-20) * Minor syntax fix and updated doc location diff --git a/README.md b/README.md index 5f1b70e..55b6dd7 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ API Documentation: https://gborough.github.io/safemoney/safemoney # SAFEMONEY +(This library is currently experimental and still working towards production-ready, all contributions are welcome) + A type safe money manipulation library for ocaml, currently supporting user-defined currency types as well as all ISO4217 currency codes and major crypto currencies. It is well known that using float numbers for money calculation is inherently lossy and should be avoided at all cost. A classic example shows that 0.21 + 0.32 could possibly lead to 0.530003 which extra money is created out of thin air. Money calculation without context is also considered error prone (e.g. the accidental USD $10. + AUD $10. = ? $20). Also there are a number of float representations and operations do not make sense for money calculation (e.g. accidentally operating on infinity values or using functions like Float.atanh). @@ -11,7 +13,7 @@ It is well known that using float numbers for money calculation is inherently lo On the other hand money calculations using checked rational(quotient) and discrete(integer) numbers with properly established context are considered to be safe. Some of the core types of this library are based on rational and discrete numbers. Back to the previous example of 0.21 + 0.32, we can substitute using rational numbers 21/100 + 32/100 = 53/100 and clearly nothing is lost or created arbitrarily. Alternatively if we were to operate on the scale of "cents" we can then write in integers 21 + 32 = 53 which achieves the same result. This library aims to establish and uphold safety contract by providing contexts in which the calculations take place, the following examples will not compile(see user manual for more examples): ```ocaml -let open Quotient in +let open Safemoney.Quotient in let qv1 = make_qv ("AUD", make_q "30/100") in <--- AUD + @@ -21,7 +23,7 @@ qv1 + qv2 Error ``` ```ocaml -let open Discrete in +let open Safemoney.Discrete in let scale1 = Scale.make_scale "AUD" "dollar" (make_q "1/1") in <--- Unit in dollar + @@ -74,7 +76,7 @@ let zv = make_z "12345" in ... The **Quotient** type provides a context for rational number operations, taking a **string** of currency name and a **Qv** value: ```ocaml -let open Quotient in +let open Safemoney.Quotient in let qv1 = make_qv ("AUD", make_q "30/100") in let qv2 = make_qv ("AUD", make_q "20/100") in qv1 + qv2 @@ -85,7 +87,7 @@ qv1 + qv2 The **Discrete** type provides a context for integer number operations, taking a **Scale** type and a **Zv** value. The Scale type takes a currency name, an unit name and a scale ratio which denote a named division with respect to the unit account of the currency, e.g. for USD the subdivision of 100 "cent" make up to 1 "dollar" of unit account, hence the ratio is 100/1 which is represented by a Qv value: ```ocaml -let open Discrete in +let open Safemoney.Discrete in let scale = Scale.make_scale "USD" "cent" (make_q "100/1") in let dv1 = make_dv (scale, make_z "200") in let dv2 = make_dv (scale, make_z "100") in @@ -97,14 +99,14 @@ dv1 - dv2 The **Exchange** type provides a context for currency exchange mechanism, taking a source currency, destination currency and exchange rate of **Qv** value: ```ocaml -let open Exchange in +let open Safemoney.Exchange in let aud_to_nzd = make_xchg ~src: "AUD" ~dst: "NZD" (make_q "4908/4503") in ... ``` To compose exchange rate, e.g. from GBP to NZD via AUD: ```ocaml -let open Exchange in +let open Safemoney.Exchange in let gbp_to_aud = make_xchg ~src: "GBP" ~dst: "AUD" (make_q "8872/4503") in let aud_to_nzd = make_xchg ~src: "AUD" ~dst: "NZD" (make_q "4908/4503") in let gbp_to_nzd = gbp_to_aud **> aud_to_nzd in ... @@ -115,6 +117,8 @@ let gbp_to_nzd = gbp_to_aud **> aud_to_nzd in ... The **Custom** type provides a signature for user defined currency types, allowing items such as currency code, description of the currency, an optional hashmap of unit scales and Qv/Zv initialiser to be specified. Obviously this is an opinionated approach and the **Predefined** module relies on this signature, but users could optionally come up with their own signatures to cater for specific needs. Let's define a new module for a currency called CamelCoin™ by implementing Custom signature: ```ocaml +open Safemoney.Types + module CAMELCOIN : Custom = struct let symbol = "CMC" @@ -136,22 +140,22 @@ module CAMELCOIN : Custom = struct | None -> None end -let open Quotient in +let open Safemoney.Quotient in let qv1 = CAMELCOIN.make_qv (make_q "30/100") in let qv2 = CAMELCOIN.make_qv (make_q "20/100") in -let dv1 = Core.Option.value_exn (CAMELCOIN.make_dv "cent" (make_z "200")) in -let dv2 = Core.Option.value_exn (CAMELCOIN.make_dv "cent" (make_z "100")) in +let dv1 = Option.get (CAMELCOIN.make_dv "cent" (make_z "200")) in +let dv2 = Option.get (CAMELCOIN.make_dv "cent" (make_z "100")) in qv1 - qv2; dv1 + dv2; ``` ### Predefined -The **Predefined** module includes readily made ISO4217 currencies and major crypto currencies. See usage in **Custom**. +The **Predefined** module includes readily made ISO4217 currencies and major crypto currencies. See usage in signature **Custom**. ### Sealing Operations -Practically in real life when calculations are **DONE** on these safe types we might want to convert them to the float representations along with a conversion strategies, effectively sealing the operations/presenting the final result, and promise not to use it further. The **Utils** module provides such sealing functions and their effective signatures are: +Practically in real life when calculations are **DONE** on these safe types we might want to convert them to the float representations along with a conversion strategies, effectively sealing the operations/presenting the final result, and promise not to use it further. The **Ops** module provides such sealing functions and their effective signatures are: * seal_quotient -> (val seal_quotient: printing_conf:printing_conf -> qv:Safemoney.Quotient.t -> string) * seal_discrete -> (val seal_discrete: printing_conf:printing_conf -> dv:Safemoney.Discrete.t -> string) @@ -161,12 +165,14 @@ Practically in real life when calculations are **DONE** on these safe types we m The **printing_conf** specifies how the the final float number should be presented, by providing a number **Separator**, whether to print a "+" sign, number of decimal places to show and a **rounding** strategy. e.g to seal a Quotient value: ```ocaml -let open Utils in -let open Safemoney in +open Safemoney +open Safemoney.Ops + (** We make a value on the fly but usually it is the result of a chain of safe Qv type calculations **) let qv = make_qv ("USD", make_q "1234567/7") in (** Using a premade separator "sep_dot_comma" in Utils module **) -let printing_conf = { separator = sep_dot_comma; plus_sign = true; num_of_digits = Uint8.of_int 4; rounding = Truncate } in +let printing_conf = make_printing_conf ~sep:(sep_dot_comma ()) ~plus_sign:true ~num_of_digits:4 ~rounding:Truncate +in seal_quotient ~printing_conf: printing_conf ~qv: qv ``` would print "+176,366.7142" @@ -175,7 +181,7 @@ Note the sealed result is a **String** to discourage further usage ### Unsafe -This library does provide escape hatches to allow float values from unsafe part of the codebase to be returned into the safe types, if you cannot establish the chain of proof for the float safety contract then use them at your own peril. The **Utils** module provides such functions: +This library does provide escape hatches to allow float values from unsafe part of the codebase to be returned into the safe types, if you cannot establish the chain of proof for the float safety contract then use them at your own peril. The **Ops** module provides such functions: * unsafe_float_to_quotient * unsafe_float_to_discrete @@ -184,13 +190,6 @@ This library does provide escape hatches to allow float values from unsafe part Note the float value is taken as **String** to encourage "finalisation" on previously unsafe float. To guide the functions on how to correctly recognise the separator the correct one should be provided or parser error is thrown. - -## TODOs - -- Toplevel Printer - -- Preprocessor - ## License This project is licensed under the [MIT license]. diff --git a/dune-project b/dune-project index e92fc8f..2dfd853 100644 --- a/dune-project +++ b/dune-project @@ -3,7 +3,6 @@ (name safemoney) (generate_opam_files true) -(implicit_transitive_deps false) (source (github gborough/safemoney)) @@ -21,4 +20,4 @@ (authors "Geoffrey Borough") (synopsis "A type safe money manipulation library") (description "A type safe money manipulation library") - (depends (ocaml (>= 4.14.0)) core dune (zarith (>= 1.6)) stdint (angstrom (>= 0.14.0)) re2 yojson (ppx_jane (>= v0.16.0)) ppx_deriving ppx_yojson_conv ppx_deriving_yojson)) + (depends (ocaml (>= 4.14.0)) base dune zarith stdint angstrom re2 yojson ppx_deriving ppx_deriving_yojson ppx_jane (ppx_expect :with-test))) diff --git a/lib/discrete.ml b/lib/discrete.ml index 629c686..25f047d 100644 --- a/lib/discrete.ml +++ b/lib/discrete.ml @@ -1,96 +1,81 @@ -open Core - module Make (Qv : Qv_intf.S) (Zv : Zv_intf.S) = struct - exception ScaleTypeMismatch of string [@@deriving sexp, yojson] + exception ScaleTypeMismatch of string module Scale = struct - exception ValidScaleError of string [@@deriving sexp, yojson] + exception ValidScaleError of string type t = - { symbol : string - ; unit : string - ; value : Qv.t - } + { symbol: string [@compare.ignore] + ; unit: string [@compare.ignore] + ; value: Qv.t } [@@deriving compare] type showable = - { symbol_ : string [@key "symbol"] - ; unit_ : string [@key "unit"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + { symbol_: string [@key "symbol"] + ; unit_: string [@key "unit"] + ; value_: string [@key "value"] } + [@@deriving show, yojson] let check_scale scale = - if Z.gt (Qv.S.num_of_q scale) Z.zero && Z.gt (Qv.S.den_of_q scale) Z.zero + if + Z.gt (Qv.S.num_of_q scale) Z.zero + && Z.gt (Qv.S.den_of_q scale) Z.zero then true else false - ;; let make_scale symbol unit value = - if check_scale value - then { symbol; unit; value } + if check_scale value then {symbol; unit; value} else raise (ValidScaleError "Valid scale must be greater than 0") - ;; - let to_showable_json x = + let to_json x = Yojson.Safe.to_string @@ showable_to_yojson - { symbol_ = x.symbol; unit_ = x.unit; value_ = Qv.S.to_str x.value } - ;; + {symbol_= x.symbol; unit_= x.unit; value_= Qv.S.to_str x.value} end - type t = - { scale : Scale.t - ; value : Zv.t - } - [@@deriving compare] + type t = {scale: Scale.t; value: Zv.t} [@@deriving compare] type showable = - { scale_ : string [@key "discrete_scale"] - ; value_ : string [@key "discrete_value"] - } - [@@deriving show, sexp, yojson] + { scale_: string [@key "discrete_scale"] + ; value_: string [@key "discrete_value"] } + [@@deriving show, yojson] + + let check_scale t1 t2 = + if Scale.compare t1.scale t2.scale = 0 then true else false - let check_scale t1 t2 = if Scale.compare t1.scale t2.scale = 0 then true else false - let make_dv (scale, value) = { scale; value } + let make_dv (scale, value) = {scale; value} let show_scale t = - Printf.printf "(%s %s %s)" t.scale.symbol t.scale.unit (Qv.S.to_str t.scale.value) - ;; + Printf.printf "(%s %s %s)" t.scale.symbol t.scale.unit + (Qv.S.to_str t.scale.value) let show_val t = Printf.printf "%s" (Zv.S.to_str t.value) let show_t t = - Printf.printf - "(%s %s %s %s)" - t.scale.symbol - t.scale.unit + Printf.printf "(%s %s %s %s)" t.scale.symbol t.scale.unit (Qv.S.to_str t.scale.value) (Zv.S.to_str t.value) - ;; - let neg t = { t with value = Zv.S.neg t.value } - let abs t = { t with value = Zv.S.abs t.value } + let neg t = {t with value= Zv.S.neg t.value} + + let abs t = {t with value= Zv.S.abs t.value} let ( + ) t1 t2 = - if check_scale t1 t2 - then { t1 with value = Zv.S.add t1.value t2.value } - else raise (ScaleTypeMismatch "cannot operate on two different currency scales") - ;; + if check_scale t1 t2 then {t1 with value= Zv.S.add t1.value t2.value} + else + raise + (ScaleTypeMismatch "cannot operate on two different currency scales") let ( - ) t1 t2 = - if check_scale t1 t2 - then { t1 with value = Zv.S.sub t1.value t2.value } - else raise (ScaleTypeMismatch "cannot operate on two different currency scales") - ;; + if check_scale t1 t2 then {t1 with value= Zv.S.sub t1.value t2.value} + else + raise + (ScaleTypeMismatch "cannot operate on two different currency scales") - let ( * ) ~t ~value = { t with value = Zv.S.mul t.value value } + let ( * ) ~t ~value = {t with value= Zv.S.mul t.value value} - let to_showable_json x = + let to_json x = Yojson.Safe.to_string @@ showable_to_yojson - { scale_ = Scale.to_showable_json x.scale - ; value_ = Zv.S.to_showable_json x.value - } - ;; + {scale_= Scale.to_json x.scale; value_= Zv.S.to_json x.value} end diff --git a/lib/discrete.mli b/lib/discrete.mli index c018b88..43de60a 100644 --- a/lib/discrete.mli +++ b/lib/discrete.mli @@ -10,10 +10,9 @@ module Make (Qv : Qv_intf.S) (Zv : Zv_intf.S) : sig (** {1 Types} *) type t = - { symbol : string (** Currency Symbol *) - ; unit : string (** Currency Unit Name *) - ; value : Qv.t (** Scale Value in Rational *) - } + { symbol: string (** Currency Symbol *) + ; unit: string (** Currency Unit Name *) + ; value: Qv.t (** Scale Value in Rational *) } [@@deriving compare] (** Scale Representation @@ -23,64 +22,59 @@ module Make (Qv : Qv_intf.S) (Zv : Zv_intf.S) : sig (** showable for t *) type showable = - { symbol_ : string [@key "symbol"] - ; unit_ : string [@key "unit"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + { symbol_: string [@key "symbol"] + ; unit_: string [@key "unit"] + ; value_: string [@key "value"] } + [@@deriving show, yojson] (** {1 Construction} *) val make_scale : string -> string -> Qv.t -> t (** Construct exchange rate, e.g. make_scale "GBP" "penny" Utils.make_q("100/1") *) - (** Required scale to be position *) val check_scale : Qv.t -> bool + (** Required scale to be position *) - (** Convert t to showable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert t to json *) end (** {1 Types} *) type t = - { scale : Scale.t (** Scale Setting *) - ; value : Zv.t (** Integer Value *) - } + {scale: Scale.t (** Scale Setting *); value: Zv.t (** Integer Value *)} (** showable for t *) type showable = - { scale_ : string [@key "scale"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + {scale_: string [@key "scale"]; value_: string [@key "value"]} + [@@deriving show, yojson] (** {1 Construction} *) val make_dv : Scale.t * Zv.t -> t (** Construct discrete value*) - (** Print the scale setting *) val show_scale : t -> unit + (** Print the scale setting *) - (** Print the integer value *) val show_val : t -> unit + (** Print the integer value *) - (** Print the discrete value *) val show_t : t -> unit + (** Print the discrete value *) - (** Negate a discrete integer value *) val neg : t -> t + (** Negate a discrete integer value *) - (** Return an absolute discrete integer value *) val abs : t -> t + (** Return an absolute discrete integer value *) - (** Add two discrete integer values *) val ( + ) : t -> t -> t + (** Add two discrete integer values *) - (** Substract two discrete integer values *) val ( - ) : t -> t -> t + (** Substract two discrete integer values *) - (** Multiply two discrete integer values *) val ( * ) : t:t -> value:Zv.t -> t + (** Multiply two discrete integer values *) - (** Convert t to showable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert t to json *) end diff --git a/lib/dune b/lib/dune index 069c21d..8448634 100644 --- a/lib/dune +++ b/lib/dune @@ -1,10 +1,8 @@ (library (public_name safemoney) - (name safemoney_lib) + (name safemoney) (libraries base - base.base_internalhash_types - core zarith stdint angstrom @@ -13,5 +11,3 @@ ppx_deriving_yojson.runtime) (preprocess (pps ppx_jane ppx_deriving_yojson ppx_deriving.show))) - -(include_subdirs unqualified) diff --git a/lib/exchange.ml b/lib/exchange.ml index 2947a8d..58bcf51 100644 --- a/lib/exchange.ml +++ b/lib/exchange.ml @@ -1,46 +1,40 @@ -open Core - module Make (Qv : Qv_intf.S) = struct - exception IntermediaryMismatch of string [@@deriving sexp, yojson] - - module Quotient = Quotient.Make + exception IntermediaryMismatch of string type t = - { src : string - ; dst : string - ; value : Qv.t - } + { src: string [@compare.ignore] + ; dst: string [@compare.ignore] + ; value: Qv.t } [@@deriving compare] type showable = - { src_ : string [@key "src"] - ; dst_ : string [@key "dst"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + { src_: string [@key "src"] + ; dst_: string [@key "dst"] + ; value_: string [@key "value"] } + [@@deriving show, yojson] let make_xchg ~src ~dst value = let value = Qv.S.abs value in - { src; dst; value } - ;; + {src; dst; value} let show_xchg t = - Printf.printf "Exchange rate from %s to %s: %s" t.src t.dst (Qv.S.to_str t.value) - ;; + Printf.printf "Exchange rate from %s to %s: %s" t.src t.dst + (Qv.S.to_str t.value) let ( **> ) t1 t2 = - if String.compare t1.dst t2.src = 0 - then { src = t1.src; dst = t2.dst; value = Qv.S.mul t1.value t2.value } + if String.compare t1.dst t2.src = 0 then + {src= t1.src; dst= t2.dst; value= Qv.S.mul t1.value t2.value} else raise (IntermediaryMismatch - "Intermediary currency symbol must be equal in order to compose exchange rate") - ;; + "Intermediary currency symbol must be equal in order to compose \ + exchange rate" ) - let xchg_recip t = { src = t.dst; dst = t.src; value = Qv.S.div Qv.S.one t.value } + let xchg_recip t = + {src= t.dst; dst= t.src; value= Qv.S.div (Qv.S.one ()) t.value} - let to_showable_json x = + let to_json x = Yojson.Safe.to_string - @@ showable_to_yojson { src_ = x.src; dst_ = x.dst; value_ = Qv.S.to_str x.value } - ;; + @@ showable_to_yojson + {src_= x.src; dst_= x.dst; value_= Qv.S.to_str x.value} end diff --git a/lib/exchange.mli b/lib/exchange.mli index f4bb3d6..33ba518 100644 --- a/lib/exchange.mli +++ b/lib/exchange.mli @@ -5,33 +5,31 @@ module Make (Qv : Qv_intf.S) : sig (** {1 Types} *) type t = - { src : string (** Source. *) - ; dst : string (** Destination. *) - ; value : Qv.t (** Exhange Rate. *) - } + { src: string (** Source. *) + ; dst: string (** Destination. *) + ; value: Qv.t (** Exhange Rate. *) } [@@deriving compare] (** showable for t *) type showable = - { src_ : string [@key "src"] - ; dst_ : string [@key "dst"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + { src_: string [@key "src"] + ; dst_: string [@key "dst"] + ; value_: string [@key "value"] } + [@@deriving show, yojson] (** {1 Construction} *) val make_xchg : src:string -> dst:string -> Qv.t -> t (** Construct exchange rate, e.g. make_xchg "GBP" "AUD" Utils.make_q(19400/1000) *) - (** Print the exchange rate*) val show_xchg : t -> unit + (** Print the exchange rate*) - (** Exchange rate composition *) val ( **> ) : t -> t -> t + (** Exchange rate composition *) - (** Apply reciprocal to exchange rate. xchg_recip (xchg_recip xchg) = id *) val xchg_recip : t -> t + (** Apply reciprocal to exchange rate. xchg_recip (xchg_recip xchg) = id *) - (** Convert t to showable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert t to json*) end diff --git a/lib/ops.ml b/lib/ops.ml new file mode 100644 index 0000000..76a6587 --- /dev/null +++ b/lib/ops.ml @@ -0,0 +1,228 @@ +open Base +open Stdint +open Types + +type rounding = + | Up + | Down + | Nearest + | NearestHalfToEven + | TowardsZero + | WithDecimalPrecision + | Truncate + +module Separator = struct + type t = string * string option + + let make_exn (c1, c2) = + if Char.is_digit c1 || Char.is_whitespace c1 then + failwith "C1 separator type not allowed" + else + match c2 with + | Some c2 -> + if Char.compare c1 c2 = 0 then + failwith "Separator must be different as per convention" + else if Char.is_digit c2 || Char.is_whitespace c2 then + failwith "C2 separator type not allowed" + else (String.of_char c1, Some (String.of_char c2)) + | None -> (String.of_char c1, None) + + let fst x = fst x + + let snd x = snd x +end + +type printing_conf = + { separator: Separator.t + ; plus_sign: bool + ; num_of_digits: Uint8.t + ; rounding: rounding } + +let make_printing_conf ~sep ~plus_sign ~num_of_digits ~rounding = + { separator= sep + ; plus_sign + ; num_of_digits= Uint8.of_int num_of_digits + ; rounding } + +let sep_comma () = Separator.make_exn (',', None) + +let sep_comma_dot () = Separator.make_exn (',', Some '.') + +let sep_comma_space () = Separator.make_exn (',', Some '_') + +let sep_dot () = Separator.make_exn ('.', None) + +let sep_dot_comma () = Separator.make_exn ('.', Some ',') + +let sep_dot_space () = Separator.make_exn ('.', Some '_') + +let default_printing_conf () = + make_printing_conf ~sep:(sep_dot ()) ~plus_sign:false ~num_of_digits:2 + ~rounding:Up + +(** Mark a positive integer value with thousand separator configuration + e.g. [mark_thousands ~v: 1234567 ~sep: ","] + would print "1,234,567" *) +let mark_thousands ~v ~sep = + let k = 1000 in + if Int.compare v k < 0 then Int.to_string v + else + let divmod num den = (Int.( / ) num den, Int.rem num den) in + let aux ~sep ~i = + match divmod i k with + | 0, 0 -> None + | 0, rem -> Some (Int.to_string rem, 0) + | quo, rem -> + if Int.compare rem 10 < 0 then + Some (sep ^ "0" ^ "0" ^ Int.to_string rem, quo) + else if Int.compare rem 100 < 0 then + Some (sep ^ "0" ^ Int.to_string rem, quo) + else Some (sep ^ Int.to_string rem, quo) + in + Sequence.fold ~init:"" ~f:(Fn.flip ( ^ )) + (Sequence.unfold ~init:v ~f:(fun i -> aux ~sep ~i)) + +let q_to_decimal ~printing_conf ~qv = + let qv = Qv.S.to_float qv in + let sep1 = Separator.fst printing_conf.separator in + let sep2 = + Option.value (Separator.snd printing_conf.separator) ~default:"" + in + let num_of_digits = Uint8.to_int printing_conf.num_of_digits in + let modf_aux v = + ( Float.Parts.integral @@ Float.modf v + , Float.abs @@ Float.Parts.fractional @@ Float.modf v ) + in + let sign_aux v = + match Float.sign_exn @@ fst v with + | Sign.Pos -> if printing_conf.plus_sign then "+" else "" + | Sign.Neg -> "-" + | _ -> "" + in + let print_aux v = + let parts = modf_aux v in + let sign = sign_aux parts in + sign + ^ mark_thousands ~v:(Int.abs @@ Float.to_int (fst parts)) ~sep:sep2 + ^ sep1 ^ Int.to_string + @@ Float.to_int (snd parts) + in + match printing_conf.rounding with + | Up -> print_aux @@ Float.round_up qv + | Down -> print_aux @@ Float.round_down qv + | Nearest -> print_aux @@ Float.round_nearest qv + | NearestHalfToEven -> print_aux @@ Float.round_nearest_half_to_even qv + | TowardsZero -> print_aux @@ Float.round_towards_zero qv + | WithDecimalPrecision -> + let round_decimal ?(decimal_digits = 2) qv = + Float.round_decimal ~decimal_digits qv + in + print_aux @@ round_decimal ~decimal_digits:num_of_digits qv + | Truncate -> ( + let fpair = modf_aux qv in + let sign = sign_aux fpair in + let rec aux acc n s : string = + if n = 0 then acc else aux (s ^ acc) (n - 1) s + in + let pad = aux "" num_of_digits "0" in + let f_part v = + Option.value + (List.nth (String.split (Float.to_string v) ~on:'.') 1) + ~default:"" + in + let take_digits len v = + let open Angstrom in + match parse_string ~consume:Prefix (take len) v with + | Ok r -> r + | Error _ -> failwith "error parsing digits" + in + match fpair with + | 0., 0. -> sign ^ "0" ^ sep1 ^ pad + | i, 0. -> + let ipart = + mark_thousands ~v:(Int.abs @@ Float.to_int i) ~sep:sep2 + in + sign ^ ipart ^ sep1 ^ pad + | i, f -> + let fpart = f_part f in + let ipart = + mark_thousands ~v:(Int.abs @@ Float.to_int i) ~sep:sep2 + in + let len = num_of_digits - String.length fpart in + let dig = take_digits num_of_digits fpart in + if len > 0 then sign ^ ipart ^ sep1 ^ dig ^ aux "" len "0" + else sign ^ ipart ^ sep1 ^ dig ) + +(** Unsafely convert a float/decimal value of string rep to integer value. + It is unsafe in a sense that the origin of float/decimal is deemed to + be unverified by default and might be as a result of lossy operations. *) +let unsafe_integer_to_z integer = Z.to_string @@ Z.of_int integer + +let seal_quotient ~printing_conf ~(qv : Quotient.t) = + q_to_decimal ~printing_conf ~qv:qv.value + +let seal_discrete ~printing_conf ~(dv : Discrete.t) = + let z_to_q = + Qv.S.div (Qv.S.make (Zv.S.to_str dv.value ^ "/1")) dv.scale.value + in + q_to_decimal ~printing_conf ~qv:z_to_q + +let seal_exchange ~printing_conf ~(xchg : Exchange.t) = + q_to_decimal ~printing_conf ~qv:xchg.value + +let seal_scale ~printing_conf ~(scale : Discrete.Scale.t) = + q_to_decimal ~printing_conf ~qv:scale.value + +let unsafe_decimal_to_q ~decimal ~sep = + let sep1 = Separator.fst sep in + let is_eol = function '\r' | '\n' -> true | _ -> false in + let open Angstrom in + let parser = + lift3 + (fun sign ipart fpart -> + Q.to_string @@ Q.of_float + @@ Float.of_string (sign ^ ipart ^ sep1 ^ fpart) ) + ( peek_char + >>= function + | Some '-' -> advance 1 >>| fun () -> "-" + | Some '+' -> advance 1 >>| fun () -> "" + | Some c when Char.is_digit c -> return "" + | _ -> fail "failure parsing sign" ) + ( match Separator.snd sep with + | None -> take_while1 Char.is_digit + | Some sep2 -> + lift2 + (fun start rest -> start ^ rest) + ( count 3 (satisfy Char.is_digit) + <|> count 2 (satisfy Char.is_digit) + <|> count 1 (satisfy Char.is_digit) + >>| String.of_char_list ) + ( many + @@ char (Char.of_string sep2) + *> count 3 (satisfy Char.is_digit) + >>| List.concat >>| String.of_char_list ) ) + ( (char (Char.of_string sep1) >>| String.of_char) + *> ( take_while1 (fun c -> if Char.is_digit c then true else false) + <* take_till is_eol + <|> (at_end_of_input >>| fun _ -> "") ) ) + in + parse_string ~consume:All parser decimal + +let unsafe_float_to_quotient ~symbol ~decimal ~sep = + match unsafe_decimal_to_q ~decimal ~sep with + | Ok qv -> Quotient.make_qv (symbol, Qv.S.make qv) + | Error msg -> failwith msg + +let unsafe_float_to_discrete ~scale ~integer = + let r = unsafe_integer_to_z integer in + Discrete.make_dv (scale, Zv.S.make r) + +let unsafe_float_to_exchange ~src ~dst ~decimal ~sep = + match unsafe_decimal_to_q ~decimal ~sep with + | Ok qv -> Exchange.make_xchg ~src ~dst (Qv.S.make qv) + | Error msg -> failwith msg + +let unsafe_float_to_scale ~symbol ~unit ~decimal ~sep = + match unsafe_decimal_to_q ~decimal ~sep with + | Ok qv -> Discrete.Scale.make_scale symbol unit (Qv.S.make qv) + | Error msg -> failwith msg diff --git a/lib/ops.mli b/lib/ops.mli new file mode 100644 index 0000000..11b72b6 --- /dev/null +++ b/lib/ops.mli @@ -0,0 +1,125 @@ +open Types +open Stdint + +(** Float round strategies*) +type rounding = + | Up (** decimal digits ignored *) + | Down (** decimal digits ignored *) + | Nearest (** decimal digits ignored *) + | NearestHalfToEven (** decimal digits ignored *) + | TowardsZero (** decimal digits ignored *) + | WithDecimalPrecision + (** rounding up to number of decimal digits provided *) + | Truncate (** rounding down to number of decimal digits provided *) + +(** Separator Configuration *) +module Separator : sig + (** {1 Types} *) + type t = private string * string option + + (** Construction*) + val make_exn : char * char option -> t + (** e.g. make_exn (',', Some '.') *) + + val fst : t -> string + (** Get first separator *) + + val snd : t -> string option + (** Get second optional separator *) +end + +(** Printing and rounding configuration *) +type printing_conf = + { separator: Separator.t + ; plus_sign: bool + ; num_of_digits: Uint8.t + ; rounding: rounding } + +val make_printing_conf : + sep:Separator.t + -> plus_sign:bool + -> num_of_digits:int + -> rounding:rounding + -> printing_conf +(** Make printing and rounding configuration *) + +val mark_thousands : v:int -> sep:string -> string + +val sep_comma : unit -> Separator.t +(** Premade separator configuration, e.g. 1000,0 *) + +val sep_comma_dot : unit -> Separator.t +(** Premade separator configuration, e.g. 1.000,0 *) + +val sep_comma_space : unit -> Separator.t +(** Premade separator configuration, e.g. 1_000,0*) + +val sep_dot : unit -> Separator.t +(** Premade separator configuration, e.g. 1000.0 *) + +val sep_dot_comma : unit -> Separator.t +(** Premade separator configuration, e.g. 1,000.0 *) + +val sep_dot_space : unit -> Separator.t +(** Premade separator configuration, e.g. 1_000.0 *) + +val default_printing_conf : unit -> printing_conf +(** Default printing configuration *) + +val q_to_decimal : printing_conf:printing_conf -> qv:Qv.t -> string +(** Convert a rational value to string representation of a float value with a printing configuration. + e.g. [let sep_dot_comma = Separator.make_exn ('.', Some ',') in + let printing_conf = { separator = sep_dot_comma; plus_sign = true; num_of_digits = Uint8.of_int 4; rounding = Truncate } in + q_to_decimal ~printing_conf: printing_conf ~qv: (Utils.make_q "-1234567/7")] + would print "-176366.7142" *) + +val seal_quotient : printing_conf:printing_conf -> qv:Quotient.t -> string +(** Convert quotient value to the string representaion of a float value with a printing configuration. + This should be used as the final step after all operations have been carried out. *) + +val seal_discrete : printing_conf:printing_conf -> dv:Discrete.t -> string +(** Convert discrete value to the string representaion of a float value with a printing configuration. + This should be used as the final step after all operations have been carried out. *) + +val seal_exchange : printing_conf:printing_conf -> xchg:Exchange.t -> string +(** Convert exchange value to the string representaion of a float value with a printing configuration. + This should be used as the final step after all operations have been carried out. *) + +val seal_scale : + printing_conf:printing_conf -> scale:Discrete.Scale.t -> string +(** Convert scale value to the string representaion of a float value with a printing configuration. + This should be used as the final step after all operations have been carried out. *) + +val unsafe_decimal_to_q : + decimal:string -> sep:Separator.t -> (string, string) result +(** Parse the string representation of a float value with printing configuration + e.g. [ let sep = Separator.make_exn ('.', Some ',') in unsafe_decimal_to_q ~decimal : "+123,456.789"] + would convert value to "123456.789" *) + +val unsafe_float_to_quotient : + symbol:string -> decimal:string -> sep:Separator.t -> Quotient.t +(** Unsafely convert a float value of string rep to quotient value. + It is unsafe in a sense that the origin of float is deemed to + be unverified by default and might be as a result of lossy operations. *) + +val unsafe_float_to_discrete : + scale:Discrete.Scale.t -> integer:int -> Discrete.t +(** Unsafely convert a integer value of string rep to discrete value. + It is unsafe in a sense that the origin of the integer is deemed to + be unverified by default and might be as a result of lossy operations. *) + +val unsafe_float_to_exchange : + src:string -> dst:string -> decimal:string -> sep:Separator.t -> Exchange.t +(** Unsafely convert a float/decimal value of string rep to exchange value. + It is unsafe in a sense that the origin of float/decimal is deemed to + be unverified by default and might be as a result of lossy operations. *) + +val unsafe_float_to_scale : + symbol:string + -> unit:string + -> decimal:string + -> sep:Separator.t + -> Discrete.Scale.t +(** Unsafely convert a float/decimal value of string rep to scale value. + It is unsafe in a sense that the origin of float/decimal is deemed to + be unverified by default and might be as a result of lossy operations. *) diff --git a/lib/predefined.ml b/lib/predefined.ml index a46fdce..6636329 100644 --- a/lib/predefined.ml +++ b/lib/predefined.ml @@ -1,5361 +1,5427 @@ -open Core -open Safemoney +open Base +open Types (** Predefined module for Afghani *) module ISO4217_AFN : Custom = struct let symbol = "AFN" + let description = "Afghani" let units = let table = Hashtbl.create (module String) in - let afghani = Discrete.Scale.make_scale symbol "afghani" (make_q "1/1") in + let afghani = + Discrete.Scale.make_scale symbol "afghani" (make_q "1/1") + in let pul = Discrete.Scale.make_scale symbol "pul" (make_q "100/1") in - Hashtbl.set table ~key:"afghani" ~data:afghani; - Hashtbl.set table ~key:"pul" ~data:pul; + Hashtbl.set table ~key:"afghani" ~data:afghani ; + Hashtbl.set table ~key:"pul" ~data:pul ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Albanian Lek *) module ISO4217_ALL : Custom = struct let symbol = "ALL" + let description = "Albanian Lek" let units = let table = Hashtbl.create (module String) in let lek = Discrete.Scale.make_scale symbol "lek" (make_q "1/1") in - let qindarke = Discrete.Scale.make_scale symbol "qindarke" (make_q "100/1") in - Hashtbl.set table ~key:"lek" ~data:lek; - Hashtbl.set table ~key:"qindarke" ~data:qindarke; + let qindarke = + Discrete.Scale.make_scale symbol "qindarke" (make_q "100/1") + in + Hashtbl.set table ~key:"lek" ~data:lek ; + Hashtbl.set table ~key:"qindarke" ~data:qindarke ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Algerian Dinar *) module ISO4217_DZD : Custom = struct let symbol = "DZD" + let description = "Algerian Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in - let santeem = Discrete.Scale.make_scale symbol "santeem" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"santeem" ~data:santeem; + let santeem = + Discrete.Scale.make_scale symbol "santeem" (make_q "100/1") + in + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"santeem" ~data:santeem ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Angolan Kwanza *) module ISO4217_AOA : Custom = struct let symbol = "AOA" + let description = "Angolan Kwanza" let units = let table = Hashtbl.create (module String) in let kwanza = Discrete.Scale.make_scale symbol "kwanza" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"kwanza" ~data:kwanza; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"kwanza" ~data:kwanza ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for East Caribbean Dollar *) module ISO4217_XCD : Custom = struct let symbol = "XCD" + let description = "East Caribbean Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Argentine Peso *) module ISO4217_ARS : Custom = struct let symbol = "ARS" + let description = "Argentine Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Armenian Dram *) module ISO4217_AMD : Custom = struct let symbol = "AMD" + let description = "Armenian Dram" let units = let table = Hashtbl.create (module String) in let dram = Discrete.Scale.make_scale symbol "dram" (make_q "1/1") in let luma = Discrete.Scale.make_scale symbol "luma" (make_q "100/1") in - Hashtbl.set table ~key:"dram" ~data:dram; - Hashtbl.set table ~key:"luma" ~data:luma; + Hashtbl.set table ~key:"dram" ~data:dram ; + Hashtbl.set table ~key:"luma" ~data:luma ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Aruban Florin *) module ISO4217_AWG : Custom = struct let symbol = "AWG" + let description = "Aruban Florin" let units = let table = Hashtbl.create (module String) in let florin = Discrete.Scale.make_scale symbol "florin" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"florin" ~data:florin; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"florin" ~data:florin ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Australian Dollar *) module ISO4217_AUD : Custom = struct let symbol = "AUD" + let description = "Australian Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Azerbaijan Manat *) module ISO4217_AZN : Custom = struct let symbol = "AZN" + let description = "Azerbaijan Manat" let units = let table = Hashtbl.create (module String) in let manat = Discrete.Scale.make_scale symbol "qapik" (make_q "1/1") in let qapik = Discrete.Scale.make_scale symbol "qapik" (make_q "100/1") in - Hashtbl.set table ~key:"manat" ~data:manat; - Hashtbl.set table ~key:"qapik" ~data:qapik; + Hashtbl.set table ~key:"manat" ~data:manat ; + Hashtbl.set table ~key:"qapik" ~data:qapik ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bahamian Dollar *) module ISO4217_BSD : Custom = struct let symbol = "BSD" + let description = "Bahamian Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bahraini Dinar *) module ISO4217_BHD : Custom = struct let symbol = "BHD" + let description = "Bahraini Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in let fils = Discrete.Scale.make_scale symbol "fils" (make_q "1000/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"fils" ~data:fils; + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"fils" ~data:fils ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bangladeshi Taka *) module ISO4217_BDT : Custom = struct let symbol = "BDT" + let description = "Bangladeshi Taka" let units = let table = Hashtbl.create (module String) in let taka = Discrete.Scale.make_scale symbol "taka" (make_q "1/1") in let paisa = Discrete.Scale.make_scale symbol "paisa" (make_q "100/1") in - Hashtbl.set table ~key:"taka" ~data:taka; - Hashtbl.set table ~key:"paisa" ~data:paisa; + Hashtbl.set table ~key:"taka" ~data:taka ; + Hashtbl.set table ~key:"paisa" ~data:paisa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Barbados Dollar *) module ISO4217_BBD : Custom = struct let symbol = "BBD" + let description = "Barbados Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Belarusian Ruble *) module ISO4217_BYN : Custom = struct let symbol = "BYN" + let description = "Belarusian Ruble" let units = let table = Hashtbl.create (module String) in let ruble = Discrete.Scale.make_scale symbol "kapiejka" (make_q "1/1") in - let kapiejka = Discrete.Scale.make_scale symbol "kapiejka" (make_q "100/1") in - Hashtbl.set table ~key:"ruble" ~data:ruble; - Hashtbl.set table ~key:"kapiejka" ~data:kapiejka; + let kapiejka = + Discrete.Scale.make_scale symbol "kapiejka" (make_q "100/1") + in + Hashtbl.set table ~key:"ruble" ~data:ruble ; + Hashtbl.set table ~key:"kapiejka" ~data:kapiejka ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Belize Dollar *) module ISO4217_BZD : Custom = struct let symbol = "BZD" + let description = "Belize Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for CFA Franc BCEAO *) module ISO4217_XOF : Custom = struct let symbol = "XOF" + let description = "CFA Franc BCEAO" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bermudian Dollar *) module ISO4217_BMD : Custom = struct let symbol = "BMD" + let description = "Bermudian Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bhutanese Ngultrum *) module ISO4217_BTN : Custom = struct let symbol = "BTN" + let description = "Bhutanese Ngultrum" let units = let table = Hashtbl.create (module String) in - let ngultrum = Discrete.Scale.make_scale symbol "ngultrum" (make_q "100/1") in - let chetrum = Discrete.Scale.make_scale symbol "chetrum" (make_q "100/1") in - Hashtbl.set table ~key:"ngultrum" ~data:ngultrum; - Hashtbl.set table ~key:"chetrum" ~data:chetrum; + let ngultrum = + Discrete.Scale.make_scale symbol "ngultrum" (make_q "100/1") + in + let chetrum = + Discrete.Scale.make_scale symbol "chetrum" (make_q "100/1") + in + Hashtbl.set table ~key:"ngultrum" ~data:ngultrum ; + Hashtbl.set table ~key:"chetrum" ~data:chetrum ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bolivian Boliviano *) module ISO4217_BOB : Custom = struct let symbol = "BOB" + let description = "Bolivian Boliviano" let units = let table = Hashtbl.create (module String) in - let boliviano = Discrete.Scale.make_scale symbol "boliviano" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"boliviano" ~data:boliviano; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let boliviano = + Discrete.Scale.make_scale symbol "boliviano" (make_q "1/1") + in + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"boliviano" ~data:boliviano ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bolivian Mvdol *) module ISO4217_BOV : Custom = struct let symbol = "BOV" + let description = "Bolivian Mvdol" let units = let table = Hashtbl.create (module String) in let bov = Discrete.Scale.make_scale symbol "BOV" (make_q "100/1") in - Hashtbl.set table ~key:"BOV" ~data:bov; + Hashtbl.set table ~key:"BOV" ~data:bov ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bosnia-Herzegovina Convertible Marka *) module ISO4217_BAM : Custom = struct let symbol = "BAM" + let description = "Bosnia-Herzegovina Convertible Marka" let units = let table = Hashtbl.create (module String) in let mark = Discrete.Scale.make_scale symbol "mark" (make_q "1/1") in - let fening = Discrete.Scale.make_scale symbol "fening" (make_q "100/1") in - Hashtbl.set table ~key:"mark" ~data:mark; - Hashtbl.set table ~key:"fening" ~data:fening; + let fening = + Discrete.Scale.make_scale symbol "fening" (make_q "100/1") + in + Hashtbl.set table ~key:"mark" ~data:mark ; + Hashtbl.set table ~key:"fening" ~data:fening ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Botswanan Pula *) module ISO4217_BWP : Custom = struct let symbol = "BWP" + let description = "Botswanan Pula" let units = let table = Hashtbl.create (module String) in let pula = Discrete.Scale.make_scale symbol "pula" (make_q "1/1") in let thebe = Discrete.Scale.make_scale symbol "thebe" (make_q "100/1") in - Hashtbl.set table ~key:"pula" ~data:pula; - Hashtbl.set table ~key:"thebe" ~data:thebe; + Hashtbl.set table ~key:"pula" ~data:pula ; + Hashtbl.set table ~key:"thebe" ~data:thebe ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Norwegian Krone *) module ISO4217_NOK : Custom = struct let symbol = "NOK" + let description = "Norwegian Krone" let units = let table = Hashtbl.create (module String) in let krone = Discrete.Scale.make_scale symbol "krone" (make_q "1/1") in let ore = Discrete.Scale.make_scale symbol "ore" (make_q "100/1") in - Hashtbl.set table ~key:"krone" ~data:krone; - Hashtbl.set table ~key:"ore" ~data:ore; + Hashtbl.set table ~key:"krone" ~data:krone ; + Hashtbl.set table ~key:"ore" ~data:ore ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Brazilian Real *) module ISO4217_BRL : Custom = struct let symbol = "BRL" + let description = "Brazilian Real" let units = let table = Hashtbl.create (module String) in let real = Discrete.Scale.make_scale symbol "real" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"real" ~data:real; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"real" ~data:real ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Brunei Dollar *) module ISO4217_BND : Custom = struct let symbol = "BND" + let description = "Brunei Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let sen = Discrete.Scale.make_scale symbol "sen" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"sen" ~data:sen; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"sen" ~data:sen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bulgarian Lev *) module ISO4217_BGN : Custom = struct let symbol = "BGN" + let description = "Bulgarian Lev" let units = let table = Hashtbl.create (module String) in let lev = Discrete.Scale.make_scale symbol "lev" (make_q "1/1") in - let stotinka = Discrete.Scale.make_scale symbol "stotinka" (make_q "100/1") in - Hashtbl.set table ~key:"lev" ~data:lev; - Hashtbl.set table ~key:"stotinka" ~data:stotinka; + let stotinka = + Discrete.Scale.make_scale symbol "stotinka" (make_q "100/1") + in + Hashtbl.set table ~key:"lev" ~data:lev ; + Hashtbl.set table ~key:"stotinka" ~data:stotinka ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Burundi Franc *) module ISO4217_BIF : Custom = struct let symbol = "BIF" + let description = "Burundi Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cabo Verde Escudo *) module ISO4217_CVE : Custom = struct let symbol = "CVE" + let description = "Cabo Verde Escudo" let units = let table = Hashtbl.create (module String) in let escudo = Discrete.Scale.make_scale symbol "escudo" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"escudo" ~data:escudo; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"escudo" ~data:escudo ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cambodian Riel *) module ISO4217_KHR : Custom = struct let symbol = "KHR" + let description = "Cambodian Riel" let units = let table = Hashtbl.create (module String) in let riel = Discrete.Scale.make_scale symbol "r" (make_q "1/1") in let sen = Discrete.Scale.make_scale symbol "sen" (make_q "100/1") in - Hashtbl.set table ~key:"riel" ~data:riel; - Hashtbl.set table ~key:"sen" ~data:sen; + Hashtbl.set table ~key:"riel" ~data:riel ; + Hashtbl.set table ~key:"sen" ~data:sen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for CFA Franc BEAC *) module ISO4217_XAF : Custom = struct let symbol = "XAF" + let description = "CFA Franc BEAC" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Canadian Dollar *) module ISO4217_CAD : Custom = struct let symbol = "CAD" + let description = "Canadian Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cayman Islands Dollar *) module ISO4217_KYD : Custom = struct let symbol = "KYD" + let description = "Cayman Islands Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Chilean Peso *) module ISO4217_CLP : Custom = struct let symbol = "CLP" + let description = "Chilean Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Chilean Unidad de Fomento *) module ISO4217_CLF : Custom = struct let symbol = "CLF" + let description = "Chilean Unidad de Fomento" let units = let table = Hashtbl.create (module String) in let clf = Discrete.Scale.make_scale symbol "CLF" (make_q "10000/1") in - Hashtbl.set table ~key:"CLF" ~data:clf; + Hashtbl.set table ~key:"CLF" ~data:clf ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Chinese Yuan Renminbi *) module ISO4217_CNY : Custom = struct let symbol = "CNY" + let description = "Chinese Yuan Renminbi" let units = let table = Hashtbl.create (module String) in let yuan = Discrete.Scale.make_scale symbol "yuan" (make_q "1/1") in let fen = Discrete.Scale.make_scale symbol "fen" (make_q "100/1") in - Hashtbl.set table ~key:"yuan" ~data:yuan; - Hashtbl.set table ~key:"fen" ~data:fen; + Hashtbl.set table ~key:"yuan" ~data:yuan ; + Hashtbl.set table ~key:"fen" ~data:fen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Colombian Peso *) module ISO4217_COP : Custom = struct let symbol = "COP" + let description = "Colombian Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Colombian Unidad de Valor Real *) module ISO4217_COU : Custom = struct let symbol = "COU" + let description = "Colombian Unidad de Valor Real" let units = let table = Hashtbl.create (module String) in let cou = Discrete.Scale.make_scale symbol "COU" (make_q "100/1") in - Hashtbl.set table ~key:"COU" ~data:cou; + Hashtbl.set table ~key:"COU" ~data:cou ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Comorian Franc *) module ISO4217_KMF : Custom = struct let symbol = "KMF" + let description = "Comorian Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Congolese Franc *) module ISO4217_CDF : Custom = struct let symbol = "CDF" + let description = "Congolese Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Costa Rican Colon *) module ISO4217_CRC : Custom = struct let symbol = "CRC" + let description = "Costa Rican Colon" let units = let table = Hashtbl.create (module String) in let colon = Discrete.Scale.make_scale symbol "colon" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"colon" ~data:colon; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"colon" ~data:colon ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cuban Peso *) module ISO4217_CUP : Custom = struct let symbol = "CUP" + let description = "Cuban Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cuban Peso Convertible *) module ISO4217_CUC : Custom = struct let symbol = "CUC" + let description = "Cuban Peso Convertible" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Netherlands Antillean Guilder *) module ISO4217_ANG : Custom = struct let symbol = "ANG" + let description = "Netherlands Antillean Guilder" let units = let table = Hashtbl.create (module String) in - let guilder = Discrete.Scale.make_scale symbol "guilder" (make_q "1/1") in + let guilder = + Discrete.Scale.make_scale symbol "guilder" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"guilder" ~data:guilder; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"guilder" ~data:guilder ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Czech Koruna *) module ISO4217_CZK : Custom = struct let symbol = "CZK" + let description = "Czech Koruna" let units = let table = Hashtbl.create (module String) in let koruna = Discrete.Scale.make_scale symbol "koruna" (make_q "1/1") in let haler = Discrete.Scale.make_scale symbol "haler" (make_q "100/1") in - Hashtbl.set table ~key:"koruna" ~data:koruna; - Hashtbl.set table ~key:"haler" ~data:haler; + Hashtbl.set table ~key:"koruna" ~data:koruna ; + Hashtbl.set table ~key:"haler" ~data:haler ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Danish Krone *) module ISO4217_DKK : Custom = struct let symbol = "DKK" + let description = "Danish Krone" let units = let table = Hashtbl.create (module String) in let krone = Discrete.Scale.make_scale symbol "krone" (make_q "1/1") in let ore = Discrete.Scale.make_scale symbol "ore" (make_q "100/1") in - Hashtbl.set table ~key:"krone" ~data:krone; - Hashtbl.set table ~key:"ore" ~data:ore; + Hashtbl.set table ~key:"krone" ~data:krone ; + Hashtbl.set table ~key:"ore" ~data:ore ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Djibouti Franc *) module ISO4217_DJF : Custom = struct let symbol = "DJF" + let description = "Djibouti Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Dominican Peso *) module ISO4217_DOP : Custom = struct let symbol = "DOP" + let description = "Dominican Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Egyptian Pound *) module ISO4217_EGP : Custom = struct let symbol = "EGP" + let description = "Egyptian Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for El Salvador Colon *) module ISO4217_SVC : Custom = struct let symbol = "SVC" + let description = "El Salvador Colon" let units = let table = Hashtbl.create (module String) in let colon = Discrete.Scale.make_scale symbol "colon" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"colon" ~data:colon; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"colon" ~data:colon ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Eritrean Nakfa *) module ISO4217_ERN : Custom = struct let symbol = "ERN" + let description = "Eritrean Nakfa" let units = let table = Hashtbl.create (module String) in let nafka = Discrete.Scale.make_scale symbol "nafka" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"nafka" ~data:nafka; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"nafka" ~data:nafka ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Swazi Lilangeni *) module ISO4217_SZL : Custom = struct let symbol = "SZL" + let description = "Swazi Lilangeni" let units = let table = Hashtbl.create (module String) in - let lilangeni = Discrete.Scale.make_scale symbol "lilangeni" (make_q "1/1") in + let lilangeni = + Discrete.Scale.make_scale symbol "lilangeni" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"lilangeni" ~data:lilangeni; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"lilangeni" ~data:lilangeni ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Ethiopian Birr *) module ISO4217_ETB : Custom = struct let symbol = "ETB" + let description = "Ethiopian Birr" let units = let table = Hashtbl.create (module String) in let birr = Discrete.Scale.make_scale symbol "birr" (make_q "1/1") in - let santim = Discrete.Scale.make_scale symbol "santim" (make_q "100/1") in - Hashtbl.set table ~key:"birr" ~data:birr; - Hashtbl.set table ~key:"santim" ~data:santim; + let santim = + Discrete.Scale.make_scale symbol "santim" (make_q "100/1") + in + Hashtbl.set table ~key:"birr" ~data:birr ; + Hashtbl.set table ~key:"santim" ~data:santim ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Euro *) module ISO4217_EUR : Custom = struct let symbol = "EUR" + let description = "Euro" let units = let table = Hashtbl.create (module String) in let euro = Discrete.Scale.make_scale symbol "euro" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"euro" ~data:euro; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"euro" ~data:euro ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Falkland Islands Pound *) module ISO4217_FKP : Custom = struct let symbol = "FKP" + let description = "Falkland Islands Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in let penny = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"penny" ~data:penny; + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"penny" ~data:penny ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Fiji Dollar *) module ISO4217_FJD : Custom = struct let symbol = "FJD" + let description = "Fiji Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for CFP Franc *) module ISO4217_XPF : Custom = struct let symbol = "XPF" + let description = "CFP Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Pound Sterling *) module ISO4217_GBP : Custom = struct let symbol = "GBP" + let description = "Pound Sterling" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in let penny = Discrete.Scale.make_scale symbol "penny" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"penny" ~data:penny; + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"penny" ~data:penny ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Gambian Dalasi *) module ISO4217_GMD : Custom = struct let symbol = "GMD" + let description = "Gambian Dalasi" let units = let table = Hashtbl.create (module String) in let dalasi = Discrete.Scale.make_scale symbol "dalasi" (make_q "1/1") in let butut = Discrete.Scale.make_scale symbol "butut" (make_q "100/1") in - Hashtbl.set table ~key:"dalasi" ~data:dalasi; - Hashtbl.set table ~key:"butut" ~data:butut; + Hashtbl.set table ~key:"dalasi" ~data:dalasi ; + Hashtbl.set table ~key:"butut" ~data:butut ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Georgian Lari *) module ISO4217_GEL : Custom = struct let symbol = "GEL" + let description = "Georgian Lari" let units = let table = Hashtbl.create (module String) in let lari = Discrete.Scale.make_scale symbol "lari" (make_q "1/1") in let tetri = Discrete.Scale.make_scale symbol "tetri" (make_q "100/1") in - Hashtbl.set table ~key:"lari" ~data:lari; - Hashtbl.set table ~key:"tetri" ~data:tetri; + Hashtbl.set table ~key:"lari" ~data:lari ; + Hashtbl.set table ~key:"tetri" ~data:tetri ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Ghana Cedi *) module ISO4217_GHS : Custom = struct let symbol = "GHS" + let description = "Ghana Cedi" let units = let table = Hashtbl.create (module String) in let cedi = Discrete.Scale.make_scale symbol "cedi" (make_q "1/1") in - let pesewa = Discrete.Scale.make_scale symbol "pesewa" (make_q "100/1") in - Hashtbl.set table ~key:"cedi" ~data:cedi; - Hashtbl.set table ~key:"pesewa" ~data:pesewa; + let pesewa = + Discrete.Scale.make_scale symbol "pesewa" (make_q "100/1") + in + Hashtbl.set table ~key:"cedi" ~data:cedi ; + Hashtbl.set table ~key:"pesewa" ~data:pesewa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Gibraltar Pound *) module ISO4217_GIP : Custom = struct let symbol = "GIP" + let description = "Gibraltar Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in let penny = Discrete.Scale.make_scale symbol "penny" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"penny" ~data:penny; + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"penny" ~data:penny ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Guatemalan Quetzal *) module ISO4217_GTQ : Custom = struct let symbol = "GTQ" + let description = "Guatemalan Quetzal" let units = let table = Hashtbl.create (module String) in - let quetzal = Discrete.Scale.make_scale symbol "quetzal" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"quetzal" ~data:quetzal; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let quetzal = + Discrete.Scale.make_scale symbol "quetzal" (make_q "1/1") + in + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"quetzal" ~data:quetzal ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Guinean Franc *) module ISO4217_GNF : Custom = struct let symbol = "GNF" + let description = "Guinean Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Guyana Dollar *) module ISO4217_GYD : Custom = struct let symbol = "GYD" + let description = "Guyana Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Haitian Gourde *) module ISO4217_HTG : Custom = struct let symbol = "HTG" + let description = "Haitian Gourde" let units = let table = Hashtbl.create (module String) in let gourde = Discrete.Scale.make_scale symbol "gourde" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"gourde" ~data:gourde; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"gourde" ~data:gourde ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Honduran Lempira *) module ISO4217_HNL : Custom = struct let symbol = "HNL" + let description = "Honduran Lempira" let units = let table = Hashtbl.create (module String) in - let lempira = Discrete.Scale.make_scale symbol "lempira" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"lempira" ~data:lempira; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let lempira = + Discrete.Scale.make_scale symbol "lempira" (make_q "1/1") + in + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"lempira" ~data:lempira ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Hong Kong Dollar *) module ISO4217_HKD : Custom = struct let symbol = "HKD" + let description = "Hong Kong Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Hungarian Forint *) module ISO4217_HUF : Custom = struct let symbol = "HUF" + let description = "Hungarian Forint" let units = let table = Hashtbl.create (module String) in let forint = Discrete.Scale.make_scale symbol "forint" (make_q "1/1") in - let filler = Discrete.Scale.make_scale symbol "filler" (make_q "100/1") in - Hashtbl.set table ~key:"forint" ~data:forint; - Hashtbl.set table ~key:"filler" ~data:filler; + let filler = + Discrete.Scale.make_scale symbol "filler" (make_q "100/1") + in + Hashtbl.set table ~key:"forint" ~data:forint ; + Hashtbl.set table ~key:"filler" ~data:filler ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Iceland Krona *) module ISO4217_ISK : Custom = struct let symbol = "ISK" + let description = "Iceland Krona" let units = let table = Hashtbl.create (module String) in let krona = Discrete.Scale.make_scale symbol "krona" (make_q "1/1") in let eyrir = Discrete.Scale.make_scale symbol "eyrir" (make_q "100/1") in - Hashtbl.set table ~key:"krona" ~data:krona; - Hashtbl.set table ~key:"eyrir" ~data:eyrir; + Hashtbl.set table ~key:"krona" ~data:krona ; + Hashtbl.set table ~key:"eyrir" ~data:eyrir ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Indian Rupee *) module ISO4217_INR : Custom = struct let symbol = "INR" + let description = "Indian Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let paisa = Discrete.Scale.make_scale symbol "paisa" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"paisa" ~data:paisa; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"paisa" ~data:paisa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Indonesian Rupiah *) module ISO4217_IDR : Custom = struct let symbol = "IDR" + let description = "Indonesian Rupiah" let units = let table = Hashtbl.create (module String) in let rupiah = Discrete.Scale.make_scale symbol "rupiah" (make_q "1/1") in let sen = Discrete.Scale.make_scale symbol "sen" (make_q "100/1") in - Hashtbl.set table ~key:"rupiah" ~data:rupiah; - Hashtbl.set table ~key:"sen" ~data:sen; + Hashtbl.set table ~key:"rupiah" ~data:rupiah ; + Hashtbl.set table ~key:"sen" ~data:sen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Special Drawing Right *) module ISO4217_XDR : Custom = struct let symbol = "XDR" + let description = "Special Drawing Right" let units = let table = Hashtbl.create (module String) in let xdr = Discrete.Scale.make_scale symbol "XDR" (make_q "1/1") in - Hashtbl.set table ~key:"XDR" ~data:xdr; + Hashtbl.set table ~key:"XDR" ~data:xdr ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Iranian Rial *) module ISO4217_IRR : Custom = struct let symbol = "IRR" + let description = "Iranian Rial" let units = let table = Hashtbl.create (module String) in let rial = Discrete.Scale.make_scale symbol "rial" (make_q "1/1") in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "100/1") in - Hashtbl.set table ~key:"rial" ~data:rial; - Hashtbl.set table ~key:"dinar" ~data:dinar; + Hashtbl.set table ~key:"rial" ~data:rial ; + Hashtbl.set table ~key:"dinar" ~data:dinar ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Iraqi Dinar *) module ISO4217_IQD : Custom = struct let symbol = "IQD" + let description = "Iraqi Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in let fils = Discrete.Scale.make_scale symbol "fils" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"fils" ~data:fils; + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"fils" ~data:fils ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for New Israeli Sheqel *) module ISO4217_ILS : Custom = struct let symbol = "ILS" + let description = "New Israeli Sheqel" let units = let table = Hashtbl.create (module String) in let shekel = Discrete.Scale.make_scale symbol "shekel" (make_q "1/1") in let agora = Discrete.Scale.make_scale symbol "agora" (make_q "100/1") in - Hashtbl.set table ~key:"shekel" ~data:shekel; - Hashtbl.set table ~key:"agora" ~data:agora; + Hashtbl.set table ~key:"shekel" ~data:shekel ; + Hashtbl.set table ~key:"agora" ~data:agora ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Jamaican Dollar *) module ISO4217_JMD : Custom = struct let symbol = "JMD" + let description = "Jamaican Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Japenese Yen *) module ISO4217_JPY : Custom = struct let symbol = "JPY" + let description = "Japenese Yen" let units = let table = Hashtbl.create (module String) in let yen = Discrete.Scale.make_scale symbol "yen" (make_q "1/1") in let sen = Discrete.Scale.make_scale symbol "sen" (make_q "100/1") in - Hashtbl.set table ~key:"yen" ~data:yen; - Hashtbl.set table ~key:"sen" ~data:sen; + Hashtbl.set table ~key:"yen" ~data:yen ; + Hashtbl.set table ~key:"sen" ~data:sen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Jordanian Dinar *) module ISO4217_JOD : Custom = struct let symbol = "JOD" + let description = "Jordanian Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Kazakhstani Tenge *) module ISO4217_KZT : Custom = struct let symbol = "KZT" + let description = "Kazakhstani Tenge" let units = let table = Hashtbl.create (module String) in let tenge = Discrete.Scale.make_scale symbol "tenge" (make_q "1/1") in let tiyin = Discrete.Scale.make_scale symbol "tiyin" (make_q "100/1") in - Hashtbl.set table ~key:"tenge" ~data:tenge; - Hashtbl.set table ~key:"tiyin" ~data:tiyin; + Hashtbl.set table ~key:"tenge" ~data:tenge ; + Hashtbl.set table ~key:"tiyin" ~data:tiyin ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Kenyan Shilling *) module ISO4217_KES : Custom = struct let symbol = "KES" + let description = "Kenyan Shilling" let units = let table = Hashtbl.create (module String) in - let shilling = Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") in + let shilling = + Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"shilling" ~data:shilling; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"shilling" ~data:shilling ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for North Korean Won *) module ISO4217_KPW : Custom = struct let symbol = "KPW" + let description = "North Korean Won" let units = let table = Hashtbl.create (module String) in let won = Discrete.Scale.make_scale symbol "won" (make_q "1/1") in let chon = Discrete.Scale.make_scale symbol "chon" (make_q "100/1") in - Hashtbl.set table ~key:"won" ~data:won; - Hashtbl.set table ~key:"chon" ~data:chon; + Hashtbl.set table ~key:"won" ~data:won ; + Hashtbl.set table ~key:"chon" ~data:chon ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for South Korean Won *) module ISO4217_KRW : Custom = struct let symbol = "KRW" + let description = "South Korean Won" let units = let table = Hashtbl.create (module String) in let won = Discrete.Scale.make_scale symbol "won" (make_q "1/1") in let jeon = Discrete.Scale.make_scale symbol "jeon" (make_q "100/1") in - Hashtbl.set table ~key:"won" ~data:won; - Hashtbl.set table ~key:"jeon" ~data:jeon; + Hashtbl.set table ~key:"won" ~data:won ; + Hashtbl.set table ~key:"jeon" ~data:jeon ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Kuwaiti Dinar *) module ISO4217_KWD : Custom = struct let symbol = "KWD" + let description = "Kuwaiti Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in let fils = Discrete.Scale.make_scale symbol "fils" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"fils" ~data:fils; + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"fils" ~data:fils ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Kyrgystani Som *) module ISO4217_KGS : Custom = struct let symbol = "KGS" + let description = "Kyrgystani Som" let units = let table = Hashtbl.create (module String) in let som = Discrete.Scale.make_scale symbol "som" (make_q "1/1") in let tyiyn = Discrete.Scale.make_scale symbol "tyiyn" (make_q "100/1") in - Hashtbl.set table ~key:"som" ~data:som; - Hashtbl.set table ~key:"tyiyn" ~data:tyiyn; + Hashtbl.set table ~key:"som" ~data:som ; + Hashtbl.set table ~key:"tyiyn" ~data:tyiyn ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Lao Kip *) module ISO4217_LAK : Custom = struct let symbol = "LAK" + let description = "Lao Kip" let units = let table = Hashtbl.create (module String) in let kip = Discrete.Scale.make_scale symbol "kip" (make_q "1/1") in let att = Discrete.Scale.make_scale symbol "att" (make_q "100/1") in - Hashtbl.set table ~key:"kip" ~data:kip; - Hashtbl.set table ~key:"att" ~data:att; + Hashtbl.set table ~key:"kip" ~data:kip ; + Hashtbl.set table ~key:"att" ~data:att ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Lebanese Pound *) module ISO4217_LBP : Custom = struct let symbol = "LBP" + let description = "Lebanese Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Lesotho Loti *) module ISO4217_LSL : Custom = struct let symbol = "LSL" + let description = "Lesotho Loti" let units = let table = Hashtbl.create (module String) in let loti = Discrete.Scale.make_scale symbol "loti" (make_q "1/1") in let sente = Discrete.Scale.make_scale symbol "sente" (make_q "100/1") in - Hashtbl.set table ~key:"loti" ~data:loti; - Hashtbl.set table ~key:"sente" ~data:sente; + Hashtbl.set table ~key:"loti" ~data:loti ; + Hashtbl.set table ~key:"sente" ~data:sente ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Liberian Dollar *) module ISO4217_LRD : Custom = struct let symbol = "LRD" + let description = "Liberian Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Libyan Dinar *) module ISO4217_LYD : Custom = struct let symbol = "LYD" + let description = "Libyan Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in - let dirham = Discrete.Scale.make_scale symbol "dirham" (make_q "1000/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"dirham" ~data:dirham; + let dirham = + Discrete.Scale.make_scale symbol "dirham" (make_q "1000/1") + in + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"dirham" ~data:dirham ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Swiss Franc *) module ISO4217_CHF : Custom = struct let symbol = "CHF" + let description = "Swiss Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let rappen = Discrete.Scale.make_scale symbol "rappen" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"rappen" ~data:rappen; + let rappen = + Discrete.Scale.make_scale symbol "rappen" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"rappen" ~data:rappen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Macanese Pataca *) module ISO4217_MOP : Custom = struct let symbol = "MOP" + let description = "Macanese Pataca" let units = let table = Hashtbl.create (module String) in let pataca = Discrete.Scale.make_scale symbol "pataca" (make_q "1/1") in let avo = Discrete.Scale.make_scale symbol "avo" (make_q "100/1") in - Hashtbl.set table ~key:"pataca" ~data:pataca; - Hashtbl.set table ~key:"avo" ~data:avo; + Hashtbl.set table ~key:"pataca" ~data:pataca ; + Hashtbl.set table ~key:"avo" ~data:avo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Macedonian Denar *) module ISO4217_MKD : Custom = struct let symbol = "MKD" + let description = "Macedonian Denar" let units = let table = Hashtbl.create (module String) in let denar = Discrete.Scale.make_scale symbol "denar" (make_q "1/1") in let deni = Discrete.Scale.make_scale symbol "deni" (make_q "100/1") in - Hashtbl.set table ~key:"denar" ~data:denar; - Hashtbl.set table ~key:"deni" ~data:deni; + Hashtbl.set table ~key:"denar" ~data:denar ; + Hashtbl.set table ~key:"deni" ~data:deni ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Malagasy Ariary *) module ISO4217_MGA : Custom = struct let symbol = "MGA" + let description = "Malagasy Ariary" let units = let table = Hashtbl.create (module String) in let ariary = Discrete.Scale.make_scale symbol "ariary" (make_q "1/1") in - let iraimbilanja = Discrete.Scale.make_scale symbol "iraimbilanja" (make_q "5/1") in - Hashtbl.set table ~key:"ariary" ~data:ariary; - Hashtbl.set table ~key:"iraimbilanja" ~data:iraimbilanja; + let iraimbilanja = + Discrete.Scale.make_scale symbol "iraimbilanja" (make_q "5/1") + in + Hashtbl.set table ~key:"ariary" ~data:ariary ; + Hashtbl.set table ~key:"iraimbilanja" ~data:iraimbilanja ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Malawi Kwacha *) module ISO4217_MWK : Custom = struct let symbol = "MWK" + let description = "Malawi Kwacha" let units = let table = Hashtbl.create (module String) in let kwacha = Discrete.Scale.make_scale symbol "kwacha" (make_q "1/1") in - let tambala = Discrete.Scale.make_scale symbol "tambala" (make_q "100/1") in - Hashtbl.set table ~key:"kwacha" ~data:kwacha; - Hashtbl.set table ~key:"tambala" ~data:tambala; + let tambala = + Discrete.Scale.make_scale symbol "tambala" (make_q "100/1") + in + Hashtbl.set table ~key:"kwacha" ~data:kwacha ; + Hashtbl.set table ~key:"tambala" ~data:tambala ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Malaysian Ringgit *) module ISO4217_MYR : Custom = struct let symbol = "MYR" + let description = "Malaysian Ringgit" let units = let table = Hashtbl.create (module String) in - let ringgit = Discrete.Scale.make_scale symbol "ringgit" (make_q "1/1") in + let ringgit = + Discrete.Scale.make_scale symbol "ringgit" (make_q "1/1") + in let sen = Discrete.Scale.make_scale symbol "sen" (make_q "100/1") in - Hashtbl.set table ~key:"ringgit" ~data:ringgit; - Hashtbl.set table ~key:"sen" ~data:sen; + Hashtbl.set table ~key:"ringgit" ~data:ringgit ; + Hashtbl.set table ~key:"sen" ~data:sen ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Maldivian Rufiyaa *) module ISO4217_MVR : Custom = struct let symbol = "MVR" + let description = "Maldivian Rufiyaa" let units = let table = Hashtbl.create (module String) in - let rufiyaa = Discrete.Scale.make_scale symbol "rufiyaa" (make_q "1/1") in + let rufiyaa = + Discrete.Scale.make_scale symbol "rufiyaa" (make_q "1/1") + in let laari = Discrete.Scale.make_scale symbol "laari" (make_q "100/1") in - Hashtbl.set table ~key:"rufiyaa" ~data:rufiyaa; - Hashtbl.set table ~key:"laari" ~data:laari; + Hashtbl.set table ~key:"rufiyaa" ~data:rufiyaa ; + Hashtbl.set table ~key:"laari" ~data:laari ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Mauritius Rupee *) module ISO4217_MUR : Custom = struct let symbol = "MUR" + let description = "Mauritius Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for ADB Unit of Account *) module ISO4217_XUA : Custom = struct let symbol = "XUA" + let description = "ADB Unit of Account" let units = let table = Hashtbl.create (module String) in let xua = Discrete.Scale.make_scale symbol "XUA" (make_q "1/1") in - Hashtbl.set table ~key:"xua" ~data:xua; + Hashtbl.set table ~key:"xua" ~data:xua ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Mexican Peso *) module ISO4217_MXN : Custom = struct let symbol = "MXN" + let description = "Mexican Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Mexican Unidad de Inversion *) module ISO4217_MXV : Custom = struct let symbol = "MXV" + let description = "Mexican Unidad de Inversion" let units = let table = Hashtbl.create (module String) in let mxv = Discrete.Scale.make_scale symbol "MXV" (make_q "100/1") in - Hashtbl.set table ~key:"mxv" ~data:mxv; + Hashtbl.set table ~key:"mxv" ~data:mxv ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Moldovan Leu *) module ISO4217_MDL : Custom = struct let symbol = "MDL" + let description = "Moldovan Leu" let units = let table = Hashtbl.create (module String) in let leu = Discrete.Scale.make_scale symbol "leu" (make_q "1/1") in let ban = Discrete.Scale.make_scale symbol "ban" (make_q "100/1") in - Hashtbl.set table ~key:"leu" ~data:leu; - Hashtbl.set table ~key:"ban" ~data:ban; + Hashtbl.set table ~key:"leu" ~data:leu ; + Hashtbl.set table ~key:"ban" ~data:ban ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Mongolian Tugrik *) module ISO4217_MNT : Custom = struct let symbol = "MNT" + let description = "Mongolian Tugrik" let units = let table = Hashtbl.create (module String) in let tugrik = Discrete.Scale.make_scale symbol "tugrik" (make_q "1/1") in let mongo = Discrete.Scale.make_scale symbol "mongo" (make_q "100/1") in - Hashtbl.set table ~key:"tugrik" ~data:tugrik; - Hashtbl.set table ~key:"mongo" ~data:mongo; + Hashtbl.set table ~key:"tugrik" ~data:tugrik ; + Hashtbl.set table ~key:"mongo" ~data:mongo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Moroccan Dirham *) module ISO4217_MAD : Custom = struct let symbol = "MAD" + let description = "Moroccan Dirham" let units = let table = Hashtbl.create (module String) in let dirham = Discrete.Scale.make_scale symbol "dirham" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"dirham" ~data:dirham; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"dirham" ~data:dirham ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Myanmar Kyat *) module ISO4217_MMK : Custom = struct let symbol = "MMK" + let description = "Myanmar Kyat" let units = let table = Hashtbl.create (module String) in let kyat = Discrete.Scale.make_scale symbol "kyat" (make_q "1/1") in let pya = Discrete.Scale.make_scale symbol "pya" (make_q "100/1") in - Hashtbl.set table ~key:"kyat" ~data:kyat; - Hashtbl.set table ~key:"pya" ~data:pya; + Hashtbl.set table ~key:"kyat" ~data:kyat ; + Hashtbl.set table ~key:"pya" ~data:pya ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Namibia Dollar *) module ISO4217_NAD : Custom = struct let symbol = "NAD" + let description = "Namibia Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Nepalese Rupee *) module ISO4217_NPR : Custom = struct let symbol = "NPR" + let description = "Nepalese Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let paisa = Discrete.Scale.make_scale symbol "paisa" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"paisa" ~data:paisa; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"paisa" ~data:paisa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for New Zealand Dollar *) module ISO4217_NZD : Custom = struct let symbol = "NZD" + let description = "New Zealand Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cordoba Oro *) module ISO4217_NIO : Custom = struct let symbol = "NIO" + let description = "Cordoba Oro" let units = let table = Hashtbl.create (module String) in - let cordoba = Discrete.Scale.make_scale symbol "cordoba" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"cordoba" ~data:cordoba; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let cordoba = + Discrete.Scale.make_scale symbol "cordoba" (make_q "1/1") + in + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"cordoba" ~data:cordoba ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Nigerian Naira *) module ISO4217_NGN : Custom = struct let symbol = "NGN" + let description = "Nigerian Naira" let units = let table = Hashtbl.create (module String) in let naira = Discrete.Scale.make_scale symbol "naira" (make_q "1/1") in let kobo = Discrete.Scale.make_scale symbol "kobo" (make_q "100/1") in - Hashtbl.set table ~key:"naira" ~data:naira; - Hashtbl.set table ~key:"kobo" ~data:kobo; + Hashtbl.set table ~key:"naira" ~data:naira ; + Hashtbl.set table ~key:"kobo" ~data:kobo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Omani Rial *) module ISO4217_OMR : Custom = struct let symbol = "OMR" + let description = "Omani Rial" let units = let table = Hashtbl.create (module String) in let rial = Discrete.Scale.make_scale symbol "rial" (make_q "1/1") in let baisa = Discrete.Scale.make_scale symbol "baisa" (make_q "100/1") in - Hashtbl.set table ~key:"rial" ~data:rial; - Hashtbl.set table ~key:"baisa" ~data:baisa; + Hashtbl.set table ~key:"rial" ~data:rial ; + Hashtbl.set table ~key:"baisa" ~data:baisa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Pakistan Rupee *) module ISO4217_PKR : Custom = struct let symbol = "PKR" + let description = "Pakistan Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let paisa = Discrete.Scale.make_scale symbol "paisa" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"paisa" ~data:paisa; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"paisa" ~data:paisa ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Panamanian Balboa *) module ISO4217_PAB : Custom = struct let symbol = "PAB" + let description = "Panamanian Balboa" let units = let table = Hashtbl.create (module String) in let balboa = Discrete.Scale.make_scale symbol "balboa" (make_q "1/1") in - let centesimo = Discrete.Scale.make_scale symbol "centesimo" (make_q "100/1") in - Hashtbl.set table ~key:"balboa" ~data:balboa; - Hashtbl.set table ~key:"centesimo" ~data:centesimo; + let centesimo = + Discrete.Scale.make_scale symbol "centesimo" (make_q "100/1") + in + Hashtbl.set table ~key:"balboa" ~data:balboa ; + Hashtbl.set table ~key:"centesimo" ~data:centesimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Papua New Guinean Kina *) module ISO4217_PGK : Custom = struct let symbol = "PGK" + let description = "Papua New Guinean Kina" let units = let table = Hashtbl.create (module String) in let kina = Discrete.Scale.make_scale symbol "kina" (make_q "1/1") in let toea = Discrete.Scale.make_scale symbol "toea" (make_q "100/1") in - Hashtbl.set table ~key:"kina" ~data:kina; - Hashtbl.set table ~key:"toea" ~data:toea; + Hashtbl.set table ~key:"kina" ~data:kina ; + Hashtbl.set table ~key:"toea" ~data:toea ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Paraguayan Guarani *) module ISO4217_PYG : Custom = struct let symbol = "PYG" + let description = "Paraguayan Guarani" let units = let table = Hashtbl.create (module String) in - let guarani = Discrete.Scale.make_scale symbol "guarani" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"guarani" ~data:guarani; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let guarani = + Discrete.Scale.make_scale symbol "guarani" (make_q "1/1") + in + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"guarani" ~data:guarani ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Peruvian Sol *) module ISO4217_PEN : Custom = struct let symbol = "PEN" + let description = "Peruvian Sol" let units = let table = Hashtbl.create (module String) in let sol = Discrete.Scale.make_scale symbol "sol" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"sol" ~data:sol; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"sol" ~data:sol ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Philippine Peso *) module ISO4217_PHP : Custom = struct let symbol = "PHP" + let description = "Philippine Peso" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centavo = Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centavo" ~data:centavo; + let centavo = + Discrete.Scale.make_scale symbol "centavo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centavo" ~data:centavo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Polish Zloty *) module ISO4217_PLN : Custom = struct let symbol = "PLN" + let description = "Polish Zloty" let units = let table = Hashtbl.create (module String) in let zloty = Discrete.Scale.make_scale symbol "zloty" (make_q "1/1") in let grosz = Discrete.Scale.make_scale symbol "grosz" (make_q "100/1") in - Hashtbl.set table ~key:"zloty" ~data:zloty; - Hashtbl.set table ~key:"grosz" ~data:grosz; + Hashtbl.set table ~key:"zloty" ~data:zloty ; + Hashtbl.set table ~key:"grosz" ~data:grosz ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Qatari Rial *) module ISO4217_QAR : Custom = struct let symbol = "QAR" + let description = "Qatari Rial" let units = let table = Hashtbl.create (module String) in let rial = Discrete.Scale.make_scale symbol "rial" (make_q "1/1") in - let dirham = Discrete.Scale.make_scale symbol "dirham" (make_q "100/1") in - Hashtbl.set table ~key:"rial" ~data:rial; - Hashtbl.set table ~key:"dirham" ~data:dirham; + let dirham = + Discrete.Scale.make_scale symbol "dirham" (make_q "100/1") + in + Hashtbl.set table ~key:"rial" ~data:rial ; + Hashtbl.set table ~key:"dirham" ~data:dirham ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Romanian Leu *) module ISO4217_RON : Custom = struct let symbol = "RON" + let description = "Romanian Leu" let units = let table = Hashtbl.create (module String) in let leu = Discrete.Scale.make_scale symbol "leu" (make_q "1/1") in let ban = Discrete.Scale.make_scale symbol "ban" (make_q "100/1") in - Hashtbl.set table ~key:"leu" ~data:leu; - Hashtbl.set table ~key:"ban" ~data:ban; + Hashtbl.set table ~key:"leu" ~data:leu ; + Hashtbl.set table ~key:"ban" ~data:ban ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Russian Ruble *) module ISO4217_RUB : Custom = struct let symbol = "RUB" + let description = "Russian Ruble" let units = let table = Hashtbl.create (module String) in let ruble = Discrete.Scale.make_scale symbol "ruble" (make_q "1/1") in let kopek = Discrete.Scale.make_scale symbol "kopek" (make_q "100/1") in - Hashtbl.set table ~key:"ruble" ~data:ruble; - Hashtbl.set table ~key:"kopek" ~data:kopek; + Hashtbl.set table ~key:"ruble" ~data:ruble ; + Hashtbl.set table ~key:"kopek" ~data:kopek ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Rwanda Franc *) module ISO4217_RWF : Custom = struct let symbol = "RWF" + let description = "Rwanda Franc" let units = let table = Hashtbl.create (module String) in let franc = Discrete.Scale.make_scale symbol "franc" (make_q "1/1") in - let centime = Discrete.Scale.make_scale symbol "centime" (make_q "100/1") in - Hashtbl.set table ~key:"franc" ~data:franc; - Hashtbl.set table ~key:"centime" ~data:centime; + let centime = + Discrete.Scale.make_scale symbol "centime" (make_q "100/1") + in + Hashtbl.set table ~key:"franc" ~data:franc ; + Hashtbl.set table ~key:"centime" ~data:centime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Saint Helena Pound *) module ISO4217_SHP : Custom = struct let symbol = "SHP" + let description = "Saint Helena Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in let penny = Discrete.Scale.make_scale symbol "penny" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"penny" ~data:penny; + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"penny" ~data:penny ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Samoan Tala *) module ISO4217_WST : Custom = struct let symbol = "WST" + let description = "Samoan Tala" let units = let table = Hashtbl.create (module String) in let tala = Discrete.Scale.make_scale symbol "tala" (make_q "1/1") in let sene = Discrete.Scale.make_scale symbol "sene" (make_q "100/1") in - Hashtbl.set table ~key:"tala" ~data:tala; - Hashtbl.set table ~key:"sene" ~data:sene; + Hashtbl.set table ~key:"tala" ~data:tala ; + Hashtbl.set table ~key:"sene" ~data:sene ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sao Tome and Principe Dobra *) module ISO4217_STN : Custom = struct let symbol = "STN" + let description = "Sao Tome and Principe Dobra" let units = let table = Hashtbl.create (module String) in let dobra = Discrete.Scale.make_scale symbol "dobra" (make_q "1/1") in - let centimos = Discrete.Scale.make_scale symbol "centimos" (make_q "100/1") in - Hashtbl.set table ~key:"dobra" ~data:dobra; - Hashtbl.set table ~key:"centimos" ~data:centimos; + let centimos = + Discrete.Scale.make_scale symbol "centimos" (make_q "100/1") + in + Hashtbl.set table ~key:"dobra" ~data:dobra ; + Hashtbl.set table ~key:"centimos" ~data:centimos ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Saudi Riyal *) module ISO4217_SAR : Custom = struct let symbol = "SAR" + let description = "Saudi Riyal" let units = let table = Hashtbl.create (module String) in let riyal = Discrete.Scale.make_scale symbol "riyal" (make_q "1/1") in - let halala = Discrete.Scale.make_scale symbol "halala" (make_q "100/1") in - Hashtbl.set table ~key:"riyal" ~data:riyal; - Hashtbl.set table ~key:"halala" ~data:halala; + let halala = + Discrete.Scale.make_scale symbol "halala" (make_q "100/1") + in + Hashtbl.set table ~key:"riyal" ~data:riyal ; + Hashtbl.set table ~key:"halala" ~data:halala ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Serbian Dinar *) module ISO4217_RSD : Custom = struct let symbol = "RSD" + let description = "Serbian Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in let para = Discrete.Scale.make_scale symbol "para" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"para" ~data:para; + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"para" ~data:para ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Seychelles Rupee *) module ISO4217_SCR : Custom = struct let symbol = "SCR" + let description = "Seychelles Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sierra Leonean Leone *) module ISO4217_SLL : Custom = struct let symbol = "SLL" + let description = "Sierra Leonean Leone" let units = let table = Hashtbl.create (module String) in let leone = Discrete.Scale.make_scale symbol "leone" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"leone" ~data:leone; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"leone" ~data:leone ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sierra Leonean Leone *) module ISO4217_SLE : Custom = struct let symbol = "SLE" + let description = "Sierra Leonean Leone" let units = let table = Hashtbl.create (module String) in let leone = Discrete.Scale.make_scale symbol "leone" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"leone" ~data:leone; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"leone" ~data:leone ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Singapore Dollar *) module ISO4217_SGD : Custom = struct let symbol = "SGD" + let description = "Singapore Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sucre *) module ISO4217_XSU : Custom = struct let symbol = "XSU" + let description = "Sucre" let units = let table = Hashtbl.create (module String) in let xsu = Discrete.Scale.make_scale symbol "XSU" (make_q "1/1") in - Hashtbl.set table ~key:"xsu" ~data:xsu; + Hashtbl.set table ~key:"xsu" ~data:xsu ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Solomon Islands Dollar *) module ISO4217_SBD : Custom = struct let symbol = "SBD" + let description = "Solomon Islands Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Somali Shilling *) module ISO4217_SOS : Custom = struct let symbol = "SOS" + let description = "Somali Shilling" let units = let table = Hashtbl.create (module String) in - let shilling = Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") in + let shilling = + Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"shilling" ~data:shilling; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"shilling" ~data:shilling ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for South African Rand *) module ISO4217_ZAR : Custom = struct let symbol = "ZAR" + let description = "South African Rand" let units = let table = Hashtbl.create (module String) in let rand = Discrete.Scale.make_scale symbol "rand" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"rand" ~data:rand; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"rand" ~data:rand ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for South Sudanese Pound *) module ISO4217_SSP : Custom = struct let symbol = "SSP" + let description = "South Sudanese Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sri Lanka Rupee *) module ISO4217_LKR : Custom = struct let symbol = "LKR" + let description = "Sri Lanka Rupee" let units = let table = Hashtbl.create (module String) in let rupee = Discrete.Scale.make_scale symbol "rupee" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"rupee" ~data:rupee; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"rupee" ~data:rupee ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Sudanese Pound *) module ISO4217_SDG : Custom = struct let symbol = "SDG" + let description = "Sudanese Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Surinam Dollar *) module ISO4217_SRD : Custom = struct let symbol = "SRD" + let description = "Surinam Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Swedish Krona *) module ISO4217_SEK : Custom = struct let symbol = "SEK" + let description = "Swedish Krona" let units = let table = Hashtbl.create (module String) in let krona = Discrete.Scale.make_scale symbol "krona" (make_q "1/1") in let ore = Discrete.Scale.make_scale symbol "ore" (make_q "100/1") in - Hashtbl.set table ~key:"krona" ~data:krona; - Hashtbl.set table ~key:"ore" ~data:ore; + Hashtbl.set table ~key:"krona" ~data:krona ; + Hashtbl.set table ~key:"ore" ~data:ore ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for WIR Euro *) module ISO4217_CHE : Custom = struct let symbol = "CHE" + let description = "WIR Euro" let units = let table = Hashtbl.create (module String) in let che = Discrete.Scale.make_scale symbol "CHE" (make_q "100/1") in - Hashtbl.set table ~key:"che" ~data:che; + Hashtbl.set table ~key:"che" ~data:che ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Syrian Pound *) module ISO4217_SYP : Custom = struct let symbol = "SYP" + let description = "Syrian Pound" let units = let table = Hashtbl.create (module String) in let pound = Discrete.Scale.make_scale symbol "pound" (make_q "1/1") in - let piastre = Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") in - Hashtbl.set table ~key:"pound" ~data:pound; - Hashtbl.set table ~key:"piastre" ~data:piastre; + let piastre = + Discrete.Scale.make_scale symbol "piastre" (make_q "100/1") + in + Hashtbl.set table ~key:"pound" ~data:pound ; + Hashtbl.set table ~key:"piastre" ~data:piastre ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for New Taiwan Dollar *) module ISO4217_TWD : Custom = struct let symbol = "TWD" + let description = "New Taiwan Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tajikstani Somoni *) module ISO4217_TJS : Custom = struct let symbol = "TJS" + let description = "Tajikstani Somoni" let units = let table = Hashtbl.create (module String) in let somoni = Discrete.Scale.make_scale symbol "somoni" (make_q "1/1") in let diram = Discrete.Scale.make_scale symbol "diram" (make_q "100/1") in - Hashtbl.set table ~key:"somoni" ~data:somoni; - Hashtbl.set table ~key:"diram" ~data:diram; + Hashtbl.set table ~key:"somoni" ~data:somoni ; + Hashtbl.set table ~key:"diram" ~data:diram ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tanzanian Shilling *) module ISO4217_TZS : Custom = struct let symbol = "TZS" + let description = "Tanzanian Shilling" let units = let table = Hashtbl.create (module String) in - let shilling = Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") in + let shilling = + Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"shilling" ~data:shilling; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"shilling" ~data:shilling ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Thai Baht *) module ISO4217_THB : Custom = struct let symbol = "THB" + let description = "Thai Baht" let units = let table = Hashtbl.create (module String) in let baht = Discrete.Scale.make_scale symbol "baht" (make_q "1/1") in - let satang = Discrete.Scale.make_scale symbol "satang" (make_q "100/1") in - Hashtbl.set table ~key:"baht" ~data:baht; - Hashtbl.set table ~key:"satang" ~data:satang; + let satang = + Discrete.Scale.make_scale symbol "satang" (make_q "100/1") + in + Hashtbl.set table ~key:"baht" ~data:baht ; + Hashtbl.set table ~key:"satang" ~data:satang ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tongan Pa'anga *) module ISO4217_TOP : Custom = struct let symbol = "TOP" + let description = "Tongan Pa'anga" let units = let table = Hashtbl.create (module String) in let paanga = Discrete.Scale.make_scale symbol "pa'anga" (make_q "1/1") in - let seniti = Discrete.Scale.make_scale symbol "seniti" (make_q "100/1") in - Hashtbl.set table ~key:"paanga" ~data:paanga; - Hashtbl.set table ~key:"seniti" ~data:seniti; + let seniti = + Discrete.Scale.make_scale symbol "seniti" (make_q "100/1") + in + Hashtbl.set table ~key:"paanga" ~data:paanga ; + Hashtbl.set table ~key:"seniti" ~data:seniti ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Trinidad and Tobago Dollar *) module ISO4217_TTD : Custom = struct let symbol = "TTD" + let description = "Trinidad and Tobago Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tunisian Dinar *) module ISO4217_TND : Custom = struct let symbol = "TND" + let description = "Tunisian Dinar" let units = let table = Hashtbl.create (module String) in let dinar = Discrete.Scale.make_scale symbol "dinar" (make_q "1/1") in - let millime = Discrete.Scale.make_scale symbol "millime" (make_q "100/1") in - Hashtbl.set table ~key:"dinar" ~data:dinar; - Hashtbl.set table ~key:"millime" ~data:millime; + let millime = + Discrete.Scale.make_scale symbol "millime" (make_q "100/1") + in + Hashtbl.set table ~key:"dinar" ~data:dinar ; + Hashtbl.set table ~key:"millime" ~data:millime ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Turkish Lira *) module ISO4217_TRY : Custom = struct let symbol = "TRY" + let description = "Turkish Lira" let units = let table = Hashtbl.create (module String) in let lira = Discrete.Scale.make_scale symbol "lira" (make_q "1/1") in let kurus = Discrete.Scale.make_scale symbol "kurus" (make_q "100/1") in - Hashtbl.set table ~key:"kurus" ~data:lira; - Hashtbl.set table ~key:"kurus" ~data:kurus; + Hashtbl.set table ~key:"kurus" ~data:lira ; + Hashtbl.set table ~key:"kurus" ~data:kurus ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Turkmenistan New Manat *) module ISO4217_TMT : Custom = struct let symbol = "TMT" + let description = "Turkmenistan New Manat" let units = let table = Hashtbl.create (module String) in let manat = Discrete.Scale.make_scale symbol "manat" (make_q "1/1") in - let tennesi = Discrete.Scale.make_scale symbol "tennesi" (make_q "100/1") in - Hashtbl.set table ~key:"manat" ~data:manat; - Hashtbl.set table ~key:"tennesi" ~data:tennesi; + let tennesi = + Discrete.Scale.make_scale symbol "tennesi" (make_q "100/1") + in + Hashtbl.set table ~key:"manat" ~data:manat ; + Hashtbl.set table ~key:"tennesi" ~data:tennesi ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Uganda Shilling *) module ISO4217_UGX : Custom = struct let symbol = "UGX" + let description = "Uganda Shilling" let units = let table = Hashtbl.create (module String) in - let shilling = Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") in + let shilling = + Discrete.Scale.make_scale symbol "shilling" (make_q "1/1") + in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"shilling" ~data:shilling; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"shilling" ~data:shilling ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Ukrainian Hryvnia *) module ISO4217_UAH : Custom = struct let symbol = "UAH" + let description = "Ukrainian Hryvnia" let units = let table = Hashtbl.create (module String) in - let hryvnia = Discrete.Scale.make_scale symbol "hryvnia" (make_q "1/1") in - let kopiyka = Discrete.Scale.make_scale symbol "kopiyka" (make_q "100/1") in - Hashtbl.set table ~key:"hryvnia" ~data:hryvnia; - Hashtbl.set table ~key:"kopiyka" ~data:kopiyka; + let hryvnia = + Discrete.Scale.make_scale symbol "hryvnia" (make_q "1/1") + in + let kopiyka = + Discrete.Scale.make_scale symbol "kopiyka" (make_q "100/1") + in + Hashtbl.set table ~key:"hryvnia" ~data:hryvnia ; + Hashtbl.set table ~key:"kopiyka" ~data:kopiyka ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for UAE Dirham *) module ISO4217_AED : Custom = struct let symbol = "AED" + let description = "UAE Dirham" let units = let table = Hashtbl.create (module String) in let dirham = Discrete.Scale.make_scale symbol "dirham" (make_q "1/1") in let fils = Discrete.Scale.make_scale symbol "fils" (make_q "100/1") in - Hashtbl.set table ~key:"dirham" ~data:dirham; - Hashtbl.set table ~key:"fils" ~data:fils; + Hashtbl.set table ~key:"dirham" ~data:dirham ; + Hashtbl.set table ~key:"fils" ~data:fils ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for US Dollar *) module ISO4217_USD : Custom = struct let symbol = "USD" + let description = "US Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for US Dollar (Next day) *) module ISO4217_USN : Custom = struct let symbol = "USN" + let description = "US Dollar (Next day)" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Peso Uruguayo *) module ISO4217_UYU : Custom = struct let symbol = "UYU" + let description = "Peso Uruguayo" let units = let table = Hashtbl.create (module String) in let peso = Discrete.Scale.make_scale symbol "peso" (make_q "1/1") in - let centesimo = Discrete.Scale.make_scale symbol "centesimo" (make_q "100/1") in - Hashtbl.set table ~key:"peso" ~data:peso; - Hashtbl.set table ~key:"centesimo" ~data:centesimo; + let centesimo = + Discrete.Scale.make_scale symbol "centesimo" (make_q "100/1") + in + Hashtbl.set table ~key:"peso" ~data:peso ; + Hashtbl.set table ~key:"centesimo" ~data:centesimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Uruguay Peso en Unidades Indexadas *) module ISO4217_UYI : Custom = struct let symbol = "UYI" + let description = "Uruguay Peso en Unidades Indexadas" let units = let table = Hashtbl.create (module String) in let uyi = Discrete.Scale.make_scale symbol "UYI" (make_q "1/1") in - Hashtbl.set table ~key:"uyi" ~data:uyi; + Hashtbl.set table ~key:"uyi" ~data:uyi ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Unidad Previsional *) module ISO4217_UYW : Custom = struct let symbol = "UYW" + let description = "Unidad Previsional" let units = let table = Hashtbl.create (module String) in let uyw = Discrete.Scale.make_scale symbol "UYW" (make_q "10000/1") in - Hashtbl.set table ~key:"uyw" ~data:uyw; + Hashtbl.set table ~key:"uyw" ~data:uyw ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Uzbekistani Sum *) module ISO4217_UZS : Custom = struct let symbol = "UZS" + let description = "Uzbekistani Sum" let units = let table = Hashtbl.create (module String) in let sum = Discrete.Scale.make_scale symbol "sum" (make_q "1/1") in let tiyin = Discrete.Scale.make_scale symbol "tiyin" (make_q "100/1") in - Hashtbl.set table ~key:"sum" ~data:sum; - Hashtbl.set table ~key:"tiyin" ~data:tiyin; + Hashtbl.set table ~key:"sum" ~data:sum ; + Hashtbl.set table ~key:"tiyin" ~data:tiyin ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Vanuatu Vatu *) module ISO4217_VUV : Custom = struct let symbol = "VUV" + let description = "Vanuatu Vatu" let units = let table = Hashtbl.create (module String) in let vatu = Discrete.Scale.make_scale symbol "vatu" (make_q "1/1") in - Hashtbl.set table ~key:"vatu" ~data:vatu; + Hashtbl.set table ~key:"vatu" ~data:vatu ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bolivar Soberano S *) module ISO4217_VES : Custom = struct let symbol = "VES" + let description = "Bolivar Soberano" let units = let table = Hashtbl.create (module String) in - let bolivar = Discrete.Scale.make_scale symbol "bolivar" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"bolivar" ~data:bolivar; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let bolivar = + Discrete.Scale.make_scale symbol "bolivar" (make_q "1/1") + in + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"bolivar" ~data:bolivar ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bolivar Soberano D *) module ISO4217_VED : Custom = struct let symbol = "VED" + let description = "Bolivar Soberano" let units = let table = Hashtbl.create (module String) in - let bolivar = Discrete.Scale.make_scale symbol "bolivar" (make_q "1/1") in - let centimo = Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") in - Hashtbl.set table ~key:"bolivar" ~data:bolivar; - Hashtbl.set table ~key:"centimo" ~data:centimo; + let bolivar = + Discrete.Scale.make_scale symbol "bolivar" (make_q "1/1") + in + let centimo = + Discrete.Scale.make_scale symbol "centimo" (make_q "100/1") + in + Hashtbl.set table ~key:"bolivar" ~data:bolivar ; + Hashtbl.set table ~key:"centimo" ~data:centimo ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Vietnamese Dong *) module ISO4217_VND : Custom = struct let symbol = "VND" + let description = "Vietnamese Dong" let units = let table = Hashtbl.create (module String) in let dong = Discrete.Scale.make_scale symbol "dong" (make_q "1/1") in let hao = Discrete.Scale.make_scale symbol "hao" (make_q "100/1") in - Hashtbl.set table ~key:"dong" ~data:dong; - Hashtbl.set table ~key:"hao" ~data:hao; + Hashtbl.set table ~key:"dong" ~data:dong ; + Hashtbl.set table ~key:"hao" ~data:hao ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Yemeni Rial *) module ISO4217_YER : Custom = struct let symbol = "YER" + let description = "Yemeni Rial" let units = let table = Hashtbl.create (module String) in let rial = Discrete.Scale.make_scale symbol "rial" (make_q "1/1") in let fils = Discrete.Scale.make_scale symbol "fils" (make_q "100/1") in - Hashtbl.set table ~key:"rial" ~data:rial; - Hashtbl.set table ~key:"fils" ~data:fils; + Hashtbl.set table ~key:"rial" ~data:rial ; + Hashtbl.set table ~key:"fils" ~data:fils ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Zambian Kwacha *) module ISO4217_ZMW : Custom = struct let symbol = "ZMW" + let description = "Zambian Kwacha" let units = let table = Hashtbl.create (module String) in let kwacha = Discrete.Scale.make_scale symbol "kwacha" (make_q "1/1") in let ngwee = Discrete.Scale.make_scale symbol "ngwee" (make_q "100/1") in - Hashtbl.set table ~key:"ngwee" ~data:kwacha; - Hashtbl.set table ~key:"ngwee" ~data:ngwee; + Hashtbl.set table ~key:"ngwee" ~data:kwacha ; + Hashtbl.set table ~key:"ngwee" ~data:ngwee ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Zimbabwe Dollar *) module ISO4217_ZWL : Custom = struct let symbol = "ZWL" + let description = "Zimbabwe Dollar" let units = let table = Hashtbl.create (module String) in let dollar = Discrete.Scale.make_scale symbol "dollar" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"dollar" ~data:dollar; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"dollar" ~data:dollar ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bond Markets Unit European Composite Unit (EURCO) *) module ISO4217_XBA : Custom = struct let symbol = "XBA" + let description = "Bond Markets Unit European Composite Unit (EURCO)" let units = let table = Hashtbl.create (module String) in let xba = Discrete.Scale.make_scale symbol "XBA" (make_q "1/1") in - Hashtbl.set table ~key:"xba" ~data:xba; + Hashtbl.set table ~key:"xba" ~data:xba ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bond Markets Unit European Composite Unit (E.M.U.-6) *) module ISO4217_XBB : Custom = struct let symbol = "XBB" + let description = "Bond Markets Unit European Monetary Unit (E.M.U.-6)" let units = let table = Hashtbl.create (module String) in let xbb = Discrete.Scale.make_scale symbol "XBB" (make_q "1/1") in - Hashtbl.set table ~key:"xbb" ~data:xbb; + Hashtbl.set table ~key:"xbb" ~data:xbb ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bond Markets Unit European Unit of Account 9 (E.U.A.-9) *) module ISO4217_XBC : Custom = struct let symbol = "XBC" + let description = "Bond Markets Unit European Unit of Account 9 (E.U.A.-9)" let units = let table = Hashtbl.create (module String) in let xbc = Discrete.Scale.make_scale symbol "XBC" (make_q "1/1") in - Hashtbl.set table ~key:"xbc" ~data:xbc; + Hashtbl.set table ~key:"xbc" ~data:xbc ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bond Markets Unit European Unit of Account 17 (E.U.A.-17) *) module ISO4217_XBD : Custom = struct let symbol = "XBD" - let description = "Bond Markets Unit European Unit of Account 17 (E.U.A.-17)" + + let description = + "Bond Markets Unit European Unit of Account 17 (E.U.A.-17)" let units = let table = Hashtbl.create (module String) in let xbd = Discrete.Scale.make_scale symbol "XBD" (make_q "1/1") in - Hashtbl.set table ~key:"xbd" ~data:xbd; + Hashtbl.set table ~key:"xbd" ~data:xbd ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Non Currency *) module ISO4217_XXX : Custom = struct let symbol = "XXX" - let description = "The codes assigned for transactions where no currency is involved" + + let description = + "The codes assigned for transactions where no currency is involved" + let units = None + let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Gold *) module ISO4217_XAU : Custom = struct let symbol = "XAU" + let description = "Gold" let units = let table = Hashtbl.create (module String) in - let troy_ounce = Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") in + let troy_ounce = + Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") + in let grain = Discrete.Scale.make_scale symbol "grain" (make_q "480/1") in - let milligrain = Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") in + let milligrain = + Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") + in let kilogram = - Discrete.Scale.make_scale symbol "kilogram" (make_q "31103477/1000000000") + Discrete.Scale.make_scale symbol "kilogram" + (make_q "31103477/1000000000") + in + let gram = + Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in - let gram = Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in let milligram = Discrete.Scale.make_scale symbol "milligram" (make_q "31103477/1000") in - let microgram = Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") in - Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce; - Hashtbl.set table ~key:"grain" ~data:grain; - Hashtbl.set table ~key:"milligrain" ~data:milligrain; - Hashtbl.set table ~key:"kilogram" ~data:kilogram; - Hashtbl.set table ~key:"gram" ~data:gram; - Hashtbl.set table ~key:"milligram" ~data:milligram; - Hashtbl.set table ~key:"microgram" ~data:microgram; + let microgram = + Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") + in + Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce ; + Hashtbl.set table ~key:"grain" ~data:grain ; + Hashtbl.set table ~key:"milligrain" ~data:milligrain ; + Hashtbl.set table ~key:"kilogram" ~data:kilogram ; + Hashtbl.set table ~key:"gram" ~data:gram ; + Hashtbl.set table ~key:"milligram" ~data:milligram ; + Hashtbl.set table ~key:"microgram" ~data:microgram ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Palladium *) module ISO4217_XPD : Custom = struct let symbol = "XPD" + let description = "Palladium" let units = let table = Hashtbl.create (module String) in - let troy_ounce = Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") in + let troy_ounce = + Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") + in let grain = Discrete.Scale.make_scale symbol "grain" (make_q "480/1") in - let milligrain = Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") in + let milligrain = + Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") + in let kilogram = - Discrete.Scale.make_scale symbol "kilogram" (make_q "31103477/1000000000") + Discrete.Scale.make_scale symbol "kilogram" + (make_q "31103477/1000000000") + in + let gram = + Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in - let gram = Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in let milligram = Discrete.Scale.make_scale symbol "milligram" (make_q "31103477/1000") in - let microgram = Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") in - Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce; - Hashtbl.set table ~key:"grain" ~data:grain; - Hashtbl.set table ~key:"milligrain" ~data:milligrain; - Hashtbl.set table ~key:"kilogram" ~data:kilogram; - Hashtbl.set table ~key:"gram" ~data:gram; - Hashtbl.set table ~key:"milligram" ~data:milligram; - Hashtbl.set table ~key:"microgram" ~data:microgram; + let microgram = + Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") + in + Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce ; + Hashtbl.set table ~key:"grain" ~data:grain ; + Hashtbl.set table ~key:"milligrain" ~data:milligrain ; + Hashtbl.set table ~key:"kilogram" ~data:kilogram ; + Hashtbl.set table ~key:"gram" ~data:gram ; + Hashtbl.set table ~key:"milligram" ~data:milligram ; + Hashtbl.set table ~key:"microgram" ~data:microgram ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Platinum *) module ISO4217_XPT : Custom = struct let symbol = "XPT" + let description = "Platinum" let units = let table = Hashtbl.create (module String) in - let troy_ounce = Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") in + let troy_ounce = + Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") + in let grain = Discrete.Scale.make_scale symbol "grain" (make_q "480/1") in - let milligrain = Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") in + let milligrain = + Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") + in let kilogram = - Discrete.Scale.make_scale symbol "kilogram" (make_q "31103477/1000000000") + Discrete.Scale.make_scale symbol "kilogram" + (make_q "31103477/1000000000") + in + let gram = + Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in - let gram = Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in let milligram = Discrete.Scale.make_scale symbol "milligram" (make_q "31103477/1000") in - let microgram = Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") in - Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce; - Hashtbl.set table ~key:"grain" ~data:grain; - Hashtbl.set table ~key:"milligrain" ~data:milligrain; - Hashtbl.set table ~key:"kilogram" ~data:kilogram; - Hashtbl.set table ~key:"gram" ~data:gram; - Hashtbl.set table ~key:"milligram" ~data:milligram; - Hashtbl.set table ~key:"microgram" ~data:microgram; + let microgram = + Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") + in + Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce ; + Hashtbl.set table ~key:"grain" ~data:grain ; + Hashtbl.set table ~key:"milligrain" ~data:milligrain ; + Hashtbl.set table ~key:"kilogram" ~data:kilogram ; + Hashtbl.set table ~key:"gram" ~data:gram ; + Hashtbl.set table ~key:"milligram" ~data:milligram ; + Hashtbl.set table ~key:"microgram" ~data:microgram ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Silver *) module ISO4217_XAG : Custom = struct let symbol = "XAG" + let description = "Silver" let units = let table = Hashtbl.create (module String) in - let troy_ounce = Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") in + let troy_ounce = + Discrete.Scale.make_scale symbol "troy-ounce" (make_q "1/1") + in let grain = Discrete.Scale.make_scale symbol "grain" (make_q "480/1") in - let milligrain = Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") in + let milligrain = + Discrete.Scale.make_scale symbol "milligrain" (make_q "480000/1") + in let kilogram = - Discrete.Scale.make_scale symbol "kilogram" (make_q "31103477/1000000000") + Discrete.Scale.make_scale symbol "kilogram" + (make_q "31103477/1000000000") + in + let gram = + Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in - let gram = Discrete.Scale.make_scale symbol "gram" (make_q "31103477/1000000") in let milligram = Discrete.Scale.make_scale symbol "milligram" (make_q "31103477/1000") in - let microgram = Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") in - Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce; - Hashtbl.set table ~key:"grain" ~data:grain; - Hashtbl.set table ~key:"milligrain" ~data:milligrain; - Hashtbl.set table ~key:"kilogram" ~data:kilogram; - Hashtbl.set table ~key:"gram" ~data:gram; - Hashtbl.set table ~key:"milligram" ~data:milligram; - Hashtbl.set table ~key:"microgram" ~data:microgram; + let microgram = + Discrete.Scale.make_scale symbol "microgram" (make_q "31103477/1") + in + Hashtbl.set table ~key:"troy-ounce" ~data:troy_ounce ; + Hashtbl.set table ~key:"grain" ~data:grain ; + Hashtbl.set table ~key:"milligrain" ~data:milligrain ; + Hashtbl.set table ~key:"kilogram" ~data:kilogram ; + Hashtbl.set table ~key:"gram" ~data:gram ; + Hashtbl.set table ~key:"milligram" ~data:milligram ; + Hashtbl.set table ~key:"microgram" ~data:microgram ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Bitcoin *) module Crypto_BTC : Custom = struct let symbol = "BTC" + let description = "Bitcoin" let units = let table = Hashtbl.create (module String) in - let bitcoin = Discrete.Scale.make_scale symbol "bitcoin" (make_q "1/1") in + let bitcoin = + Discrete.Scale.make_scale symbol "bitcoin" (make_q "1/1") + in let millibitcoin = Discrete.Scale.make_scale symbol "millibitcoin" (make_q "1000/1") in - let satoshi = Discrete.Scale.make_scale symbol "satoshi" (make_q "100000000/1") in - Hashtbl.set table ~key:"bitcoin" ~data:bitcoin; - Hashtbl.set table ~key:"millibitcoin" ~data:millibitcoin; - Hashtbl.set table ~key:"satoshi" ~data:satoshi; + let satoshi = + Discrete.Scale.make_scale symbol "satoshi" (make_q "100000000/1") + in + Hashtbl.set table ~key:"bitcoin" ~data:bitcoin ; + Hashtbl.set table ~key:"millibitcoin" ~data:millibitcoin ; + Hashtbl.set table ~key:"satoshi" ~data:satoshi ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Ethereum *) module Crypto_ETH : Custom = struct let symbol = "ETH" + let description = "Ethereum" let units = let table = Hashtbl.create (module String) in let ether = Discrete.Scale.make_scale symbol "ether" (make_q "1/1") in let kwei = Discrete.Scale.make_scale symbol "kwei" (make_q "1000/1") in - let babbage = Discrete.Scale.make_scale symbol "babbage" (make_q "1000/1") in - let mwei = Discrete.Scale.make_scale symbol "mwei" (make_q "1000000/1") in - let lovelace = Discrete.Scale.make_scale symbol "lovelace" (make_q "1000000/1") in - let gwei = Discrete.Scale.make_scale symbol "gwei" (make_q "1000000000/1") in - let shannon = Discrete.Scale.make_scale symbol "shannon" (make_q "1000000000/1") in + let babbage = + Discrete.Scale.make_scale symbol "babbage" (make_q "1000/1") + in + let mwei = + Discrete.Scale.make_scale symbol "mwei" (make_q "1000000/1") + in + let lovelace = + Discrete.Scale.make_scale symbol "lovelace" (make_q "1000000/1") + in + let gwei = + Discrete.Scale.make_scale symbol "gwei" (make_q "1000000000/1") + in + let shannon = + Discrete.Scale.make_scale symbol "shannon" (make_q "1000000000/1") + in let microether = - Discrete.Scale.make_scale symbol "microether" (make_q "1000000000000/1") + Discrete.Scale.make_scale symbol "microether" + (make_q "1000000000000/1") + in + let szabo = + Discrete.Scale.make_scale symbol "szabo" (make_q "1000000000000/1") in - let szabo = Discrete.Scale.make_scale symbol "szabo" (make_q "1000000000000/1") in let finney = Discrete.Scale.make_scale symbol "finney" (make_q "1000000000000000/1") in let milliether = - Discrete.Scale.make_scale symbol "milliether" (make_q "1000000000000000/1") + Discrete.Scale.make_scale symbol "milliether" + (make_q "1000000000000000/1") + in + let wei = + Discrete.Scale.make_scale symbol "wei" (make_q "1000000000000000000/1") in - let wei = Discrete.Scale.make_scale symbol "wei" (make_q "1000000000000000000/1") in - Hashtbl.set table ~key:"ether" ~data:ether; - Hashtbl.set table ~key:"kwei" ~data:kwei; - Hashtbl.set table ~key:"babbage" ~data:babbage; - Hashtbl.set table ~key:"mwei" ~data:mwei; - Hashtbl.set table ~key:"lovelace" ~data:lovelace; - Hashtbl.set table ~key:"gwei" ~data:gwei; - Hashtbl.set table ~key:"shannon" ~data:shannon; - Hashtbl.set table ~key:"microether" ~data:microether; - Hashtbl.set table ~key:"szabo" ~data:szabo; - Hashtbl.set table ~key:"finney" ~data:finney; - Hashtbl.set table ~key:"milliether" ~data:milliether; - Hashtbl.set table ~key:"wei" ~data:wei; + Hashtbl.set table ~key:"ether" ~data:ether ; + Hashtbl.set table ~key:"kwei" ~data:kwei ; + Hashtbl.set table ~key:"babbage" ~data:babbage ; + Hashtbl.set table ~key:"mwei" ~data:mwei ; + Hashtbl.set table ~key:"lovelace" ~data:lovelace ; + Hashtbl.set table ~key:"gwei" ~data:gwei ; + Hashtbl.set table ~key:"shannon" ~data:shannon ; + Hashtbl.set table ~key:"microether" ~data:microether ; + Hashtbl.set table ~key:"szabo" ~data:szabo ; + Hashtbl.set table ~key:"finney" ~data:finney ; + Hashtbl.set table ~key:"milliether" ~data:milliether ; + Hashtbl.set table ~key:"wei" ~data:wei ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Binance Coin *) module Crypto_BNB : Custom = struct let symbol = "BNB" + let description = "Binance Coin" let units = let table = Hashtbl.create (module String) in let bnb = Discrete.Scale.make_scale symbol "bnb" (make_q "1/1") in - let jager = Discrete.Scale.make_scale symbol "jager" (make_q "100000000/1") in - Hashtbl.set table ~key:"bnb" ~data:bnb; - Hashtbl.set table ~key:"jager" ~data:jager; + let jager = + Discrete.Scale.make_scale symbol "jager" (make_q "100000000/1") + in + Hashtbl.set table ~key:"bnb" ~data:bnb ; + Hashtbl.set table ~key:"jager" ~data:jager ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tether USDT *) module Crypto_USDT : Custom = struct let symbol = "USDT" + let description = "Tether USDT" let units = let table = Hashtbl.create (module String) in let usdt = Discrete.Scale.make_scale symbol "usdt" (make_q "1/1") in let cent = Discrete.Scale.make_scale symbol "cent" (make_q "100/1") in - Hashtbl.set table ~key:"usdt" ~data:usdt; - Hashtbl.set table ~key:"cent" ~data:cent; + Hashtbl.set table ~key:"usdt" ~data:usdt ; + Hashtbl.set table ~key:"cent" ~data:cent ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Cardano *) module Crypto_ADA : Custom = struct let symbol = "ADA" + let description = "Cardano" let units = let table = Hashtbl.create (module String) in let ada = Discrete.Scale.make_scale symbol "ada" (make_q "1/1") in - let lovelace = Discrete.Scale.make_scale symbol "lovelace" (make_q "1000000/1") in - Hashtbl.set table ~key:"ada" ~data:ada; - Hashtbl.set table ~key:"lovelace" ~data:lovelace; + let lovelace = + Discrete.Scale.make_scale symbol "lovelace" (make_q "1000000/1") + in + Hashtbl.set table ~key:"ada" ~data:ada ; + Hashtbl.set table ~key:"lovelace" ~data:lovelace ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Dogecoin *) module Crypto_DOGE : Custom = struct let symbol = "DOGE" + let description = "Dogecoin" let units = let table = Hashtbl.create (module String) in let doge = Discrete.Scale.make_scale symbol "doge" (make_q "1/1") in - let koinu = Discrete.Scale.make_scale symbol "koinu" (make_q "100000000/1") in - Hashtbl.set table ~key:"doge" ~data:doge; - Hashtbl.set table ~key:"koinu" ~data:koinu; + let koinu = + Discrete.Scale.make_scale symbol "koinu" (make_q "100000000/1") + in + Hashtbl.set table ~key:"doge" ~data:doge ; + Hashtbl.set table ~key:"koinu" ~data:koinu ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Litecoin *) module Crypto_LTC : Custom = struct let symbol = "LTC" + let description = "Litecoin" let units = let table = Hashtbl.create (module String) in - let litecoin = Discrete.Scale.make_scale symbol "litecoin" (make_q "1/1") in + let litecoin = + Discrete.Scale.make_scale symbol "litecoin" (make_q "1/1") + in let lite = Discrete.Scale.make_scale symbol "lite" (make_q "1000/1") in - let photon = Discrete.Scale.make_scale symbol "lite" (make_q "100000000/1") in - Hashtbl.set table ~key:"litecoin" ~data:litecoin; - Hashtbl.set table ~key:"lite" ~data:lite; - Hashtbl.set table ~key:"photon" ~data:photon; + let photon = + Discrete.Scale.make_scale symbol "lite" (make_q "100000000/1") + in + Hashtbl.set table ~key:"litecoin" ~data:litecoin ; + Hashtbl.set table ~key:"lite" ~data:lite ; + Hashtbl.set table ~key:"photon" ~data:photon ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Ripple *) module Crypto_XRP : Custom = struct let symbol = "XRP" + let description = "Ripple" let units = let table = Hashtbl.create (module String) in let ripple = Discrete.Scale.make_scale symbol "ripple" (make_q "1/1") in - let drop = Discrete.Scale.make_scale symbol "drop" (make_q "1000000/1") in - Hashtbl.set table ~key:"ripple" ~data:ripple; - Hashtbl.set table ~key:"drop" ~data:drop; + let drop = + Discrete.Scale.make_scale symbol "drop" (make_q "1000000/1") + in + Hashtbl.set table ~key:"ripple" ~data:ripple ; + Hashtbl.set table ~key:"drop" ~data:drop ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Monero *) module Crypto_XMR : Custom = struct let symbol = "XMR" + let description = "Monero" let units = let table = Hashtbl.create (module String) in let monero = Discrete.Scale.make_scale symbol "monero" (make_q "1/1") in - let decinero = Discrete.Scale.make_scale symbol "decinero" (make_q "10/1") in - let centinero = Discrete.Scale.make_scale symbol "centinero" (make_q "100/1") in - let millinero = Discrete.Scale.make_scale symbol "millinero" (make_q "1000/1") in - let micronero = Discrete.Scale.make_scale symbol "micronero" (make_q "1000000/1") in - let nanonero = Discrete.Scale.make_scale symbol "nanonero" (make_q "1000000000/1") in + let decinero = + Discrete.Scale.make_scale symbol "decinero" (make_q "10/1") + in + let centinero = + Discrete.Scale.make_scale symbol "centinero" (make_q "100/1") + in + let millinero = + Discrete.Scale.make_scale symbol "millinero" (make_q "1000/1") + in + let micronero = + Discrete.Scale.make_scale symbol "micronero" (make_q "1000000/1") + in + let nanonero = + Discrete.Scale.make_scale symbol "nanonero" (make_q "1000000000/1") + in let piconero = Discrete.Scale.make_scale symbol "piconero" (make_q "1000000000000/1") in - Hashtbl.set table ~key:"monero" ~data:monero; - Hashtbl.set table ~key:"decinero" ~data:decinero; - Hashtbl.set table ~key:"centinero" ~data:centinero; - Hashtbl.set table ~key:"millinero" ~data:millinero; - Hashtbl.set table ~key:"micronero" ~data:micronero; - Hashtbl.set table ~key:"nanonero" ~data:nanonero; - Hashtbl.set table ~key:"piconero" ~data:piconero; + Hashtbl.set table ~key:"monero" ~data:monero ; + Hashtbl.set table ~key:"decinero" ~data:decinero ; + Hashtbl.set table ~key:"centinero" ~data:centinero ; + Hashtbl.set table ~key:"millinero" ~data:millinero ; + Hashtbl.set table ~key:"micronero" ~data:micronero ; + Hashtbl.set table ~key:"nanonero" ~data:nanonero ; + Hashtbl.set table ~key:"piconero" ~data:piconero ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Solana *) module Crypto_SOL : Custom = struct let symbol = "SOL" + let description = "Solana" let units = let table = Hashtbl.create (module String) in let sol = Discrete.Scale.make_scale symbol "sol" (make_q "1/1") in - let lamport = Discrete.Scale.make_scale symbol "lamport" (make_q "100000000/1") in - Hashtbl.set table ~key:"sol" ~data:sol; - Hashtbl.set table ~key:"lamport" ~data:lamport; + let lamport = + Discrete.Scale.make_scale symbol "lamport" (make_q "100000000/1") + in + Hashtbl.set table ~key:"sol" ~data:sol ; + Hashtbl.set table ~key:"lamport" ~data:lamport ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Polkadot *) module Crypto_DOT : Custom = struct let symbol = "DOT" + let description = "Polkadot" let units = let table = Hashtbl.create (module String) in let dot = Discrete.Scale.make_scale symbol "dot" (make_q "1/1") in - let million = Discrete.Scale.make_scale symbol "million " (make_q "1/1000000") in - let millidot = Discrete.Scale.make_scale symbol "millidot " (make_q "1000/1") in - let microdot = Discrete.Scale.make_scale symbol "microdot " (make_q "100000/1") in - let planck = Discrete.Scale.make_scale symbol "million " (make_q "1000000000/1") in - Hashtbl.set table ~key:"dot" ~data:dot; - Hashtbl.set table ~key:"million" ~data:million; - Hashtbl.set table ~key:"millidot" ~data:millidot; - Hashtbl.set table ~key:"microdot" ~data:microdot; - Hashtbl.set table ~key:"planck" ~data:planck; + let million = + Discrete.Scale.make_scale symbol "million " (make_q "1/1000000") + in + let millidot = + Discrete.Scale.make_scale symbol "millidot " (make_q "1000/1") + in + let microdot = + Discrete.Scale.make_scale symbol "microdot " (make_q "100000/1") + in + let planck = + Discrete.Scale.make_scale symbol "million " (make_q "1000000000/1") + in + Hashtbl.set table ~key:"dot" ~data:dot ; + Hashtbl.set table ~key:"million" ~data:million ; + Hashtbl.set table ~key:"millidot" ~data:millidot ; + Hashtbl.set table ~key:"microdot" ~data:microdot ; + Hashtbl.set table ~key:"planck" ~data:planck ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Shiba inu *) module Crypto_SHIB : Custom = struct let symbol = "SHIB" + let description = "Shiba inu" let units = let table = Hashtbl.create (module String) in let shib = Discrete.Scale.make_scale symbol "dot" (make_q "1/1") in - let shiboshi = Discrete.Scale.make_scale symbol "shiboshi " (make_q "100000000/1") in - Hashtbl.set table ~key:"shib" ~data:shib; - Hashtbl.set table ~key:"shiboshi" ~data:shiboshi; + let shiboshi = + Discrete.Scale.make_scale symbol "shiboshi " (make_q "100000000/1") + in + Hashtbl.set table ~key:"shib" ~data:shib ; + Hashtbl.set table ~key:"shiboshi" ~data:shiboshi ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end (** Predefined module for Tezos *) module Crypto_XTZ : Custom = struct let symbol = "XTZ" + let description = "Tezos" let units = let table = Hashtbl.create (module String) in let tez = Discrete.Scale.make_scale symbol "tez" (make_q "1/1") in - let mutez = Discrete.Scale.make_scale symbol "mutez " (make_q "1000000/1") in - Hashtbl.set table ~key:"tez" ~data:tez; - Hashtbl.set table ~key:"mutez" ~data:mutez; + let mutez = + Discrete.Scale.make_scale symbol "mutez " (make_q "1000000/1") + in + Hashtbl.set table ~key:"tez" ~data:tez ; + Hashtbl.set table ~key:"mutez" ~data:mutez ; Some table - ;; let make_qv qv = Quotient.make_qv (symbol, qv) let make_dv unit dv = match units with | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) | None -> None - ;; end diff --git a/lib/quotient.ml b/lib/quotient.ml index 8617f04..2a71393 100644 --- a/lib/quotient.ml +++ b/lib/quotient.ml @@ -1,45 +1,47 @@ -open Core - module Make (Qv : Qv_intf.S) = struct - exception CurrencyTypeMismatch of string [@@deriving sexp, yojson] + exception CurrencyTypeMismatch of string - type t = - { symbol : string - ; value : Qv.t - } + type t = {symbol: string [@compare.ignore]; value: Qv.t} [@@deriving compare] type showable = - { symbol_ : string [@key "symbol"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + {symbol_: string [@key "symbol"]; value_: string [@key "value"]} + [@@deriving show, yojson] + + let check_sym t1 t2 = + if String.compare t1.symbol t2.symbol = 0 then true else false + + let make_qv (symbol, qv) = {symbol; value= qv} - let check_sym t1 t2 = if String.compare t1.symbol t2.symbol = 0 then true else false - let make_qv (symbol, qv) = { symbol; value = qv } let show_sym t = Printf.printf "%s" t.symbol + let show_val t = Printf.printf "%s" (Qv.S.to_str t.value) + let show_t t = Printf.printf "(%s %s)" t.symbol (Qv.S.to_str t.value) - let neg t = { t with value = Qv.S.neg t.value } - let abs t = { t with value = Qv.S.abs t.value } + + let neg t = {t with value= Qv.S.neg t.value} + + let abs t = {t with value= Qv.S.abs t.value} let ( + ) t1 t2 = - if check_sym t1 t2 - then { t1 with value = Qv.S.add t1.value t2.value } - else raise (CurrencyTypeMismatch "cannot operate on two different currency types") - ;; + if check_sym t1 t2 then {t1 with value= Qv.S.add t1.value t2.value} + else + raise + (CurrencyTypeMismatch + "cannot operate on two different currency types" ) let ( - ) t1 t2 = - if check_sym t1 t2 - then { t1 with value = Qv.S.sub t1.value t2.value } - else raise (CurrencyTypeMismatch "cannot operate on two different currency types") - ;; + if check_sym t1 t2 then {t1 with value= Qv.S.sub t1.value t2.value} + else + raise + (CurrencyTypeMismatch + "cannot operate on two different currency types" ) + + let ( * ) ~t ~value = {t with value= Qv.S.mul t.value value} - let ( * ) ~t ~value = { t with value = Qv.S.mul t.value value } - let ( / ) t value = { t with value = Qv.S.div t.value value } + let ( / ) t value = {t with value= Qv.S.div t.value value} - let to_showable_json x = + let to_json x = Yojson.Safe.to_string - @@ showable_to_yojson { symbol_ = x.symbol; value_ = Qv.S.to_str x.value } - ;; + @@ showable_to_yojson {symbol_= x.symbol; value_= Qv.S.to_str x.value} end diff --git a/lib/quotient.mli b/lib/quotient.mli index d5ce3c9..6072d66 100644 --- a/lib/quotient.mli +++ b/lib/quotient.mli @@ -7,51 +7,48 @@ module Make (Qv : Qv_intf.S) : sig (** {1 Types} *) type t = - { symbol : string (** Currency Symbol *) - ; value : Qv.t (** Value in Rational *) - } + { symbol: string (** Currency Symbol *) + ; value: Qv.t (** Value in Rational *) } [@@deriving compare] (** showable for t *) type showable = - { symbol_ : string [@key "symbol"] - ; value_ : string [@key "value"] - } - [@@deriving show, sexp, yojson] + {symbol_: string [@key "symbol"]; value_: string [@key "value"]} + [@@deriving show, yojson] (** {1 Construction} *) val make_qv : string * Qv.t -> t (** Construct quotient value, e.g. make_qv "GBP" Utils.make_q("123456/100") *) - (** Print the currency symbol *) val show_sym : t -> unit + (** Print the currency symbol *) - (** Print the currency value *) val show_val : t -> unit + (** Print the currency value *) - (** Print the quotient value *) val show_t : t -> unit + (** Print the quotient value *) - (** Negate a quotient value *) val neg : t -> t + (** Negate a quotient value *) - (** Return an absolute quotient value *) val abs : t -> t + (** Return an absolute quotient value *) - (** Add two quotient values with same symbol as required *) val ( + ) : t -> t -> t + (** Add two quotient values with same symbol as required *) - (** Substract two quotient values with same symbol as required *) val ( - ) : t -> t -> t + (** Substract two quotient values with same symbol as required *) + val ( * ) : t:t -> value:Qv.t -> t (** Multiply a quotient value with a plain rational value. Multiplying two quotient values does not make sense for currency ops. *) - val ( * ) : t:t -> value:Qv.t -> t + val ( / ) : t -> Qv.t -> t (** Divide a quotient value with a plain rational value. Dividing two quotient values does not make sense for currency ops. *) - val ( / ) : t -> Qv.t -> t - (** Convert t to showable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert t to json *) end diff --git a/lib/qv.ml b/lib/qv.ml index 454f970..4a6f742 100644 --- a/lib/qv.ml +++ b/lib/qv.ml @@ -1,51 +1,61 @@ -open Core - type t = Q.t [@@deriving compare] exception NonsensicalQuotientValue of string + exception DenominatorZero of string + exception NonQuotientRep of string module S = struct - type showable = { value : string } [@@deriving show, sexp, yojson] + type showable = {value: string} [@@deriving show, yojson] + + let one () = Q.one - let one = Q.one let neg x = Q.neg x + let abs x = Q.abs x + let signum x = Q.sign x + let add x y = Q.add x y + let sub x y = Q.sub x y + let mul x y = Q.mul x y + let div x y = Q.div x y let make str = let pat = Re2.create_exn "^-?[0-9]*/?-?[0-9]*?$" in match Re2.matches pat str with - | true -> - let q = Q.of_string str in - (match Q.classify q with - | Q.INF | Q.MINF | Q.UNDEF -> - raise - (NonsensicalQuotientValue - "nonsensical quotient values are not suitable for currency operation") - | Q.NZERO -> - if Z.compare q.den Z.zero = 0 - then raise (DenominatorZero "denominator must not be zero") - else q - | Q.ZERO -> Q.zero) - | false -> raise (NonQuotientRep "only quotient representation allowed, e.g. 123/456") - ;; + | true -> ( + let q = Q.of_string str in + match Q.classify q with + | Q.INF | Q.MINF | Q.UNDEF -> + raise + (NonsensicalQuotientValue + "nonsensical quotient values are not suitable for currency \ + operation" ) + | Q.NZERO -> + if Z.compare q.den Z.zero = 0 then + raise (DenominatorZero "denominator must not be zero") + else q + | Q.ZERO -> Q.zero ) + | false -> + raise + (NonQuotientRep + "only quotient representation allowed, e.g. 123/456" ) let num_of_q x = Q.num x + let den_of_q x = Q.den x let to_str x = - if Z.compare (den_of_q x) Z.one = 0 then Q.to_string x ^ "/1" else Q.to_string x - ;; + if Z.compare (den_of_q x) Z.one = 0 then Q.to_string x ^ "/1" + else Q.to_string x let to_float x = Q.to_float x - let to_showable_json x = - Yojson.Safe.to_string @@ showable_to_yojson { value = to_str x } - ;; + let to_json x = + Yojson.Safe.to_string @@ showable_to_yojson {value= to_str x} end diff --git a/lib/qv_intf.ml b/lib/qv_intf.ml index 79bbde3..0e6c605 100644 --- a/lib/qv_intf.ml +++ b/lib/qv_intf.ml @@ -10,58 +10,60 @@ module type S = sig (** {1 Types} *) type t = private Q.t [@@deriving compare] - exception NonsensicalQuotientValue of string [@@deriving sexp, yojson] - exception DenominatorZero of string [@@deriving sexp, yojson] - exception NonQuotientRep of string [@@deriving sexp, yojson] + exception NonsensicalQuotientValue of string + + exception DenominatorZero of string + + exception NonQuotientRep of string module S : sig (** showable for t *) - type showable = { value : string } [@@deriving show, sexp, yojson] + type showable = {value: string} [@@deriving show, yojson] - (** Construction*) + (** {1 Construction} *) val make : string -> t - (** Constructing Q by using a private type, create a Q value from string, e.g. [from_str "123/456"]. - Reason behind is to disallow a range of functions that are unsuitable for currency operations. Unsensical - and undefined rational numbers are checked/excluded.In the context of safe money we want to establish - a chain of proof that no lossy operations ever occurred. For convenience the function alias [make_q] can be used. *) + (** Constructing Q by using a private type to only allow creation from string, e.g. [from_str "123/456"]. + Reason behind is to disallow a range of functions that are unsuitable for currency operations. Nonsensical + and undefined rational numbers are checked/excluded. In the context of safe money we want to establish + a chain of proof that no lossy operations ever occurred. Helper function [make_q] is provided. *) + val one : unit -> t (** Return rational value of 1: "1/1" or "1" *) - val one : t - (** Negate a Q value *) val neg : t -> t + (** Negate a Q value *) - (** Return an absolute Q value *) val abs : t -> t + (** Return an absolute Q value *) - (** Return the sign of Q value, -1, 0, or 1 when the argument is respectively negative, null, or positive. *) val signum : t -> int + (** Return the sign of Q value, -1, 0, or 1 when the argument is respectively negative, null, or positive. *) - (** Add two Q values *) val add : t -> t -> t + (** Add two Q values *) - (** Substract two Q values *) val sub : t -> t -> t + (** Substract two Q values *) - (** Multiply two Q values *) val mul : t -> t -> t + (** Multiply two Q values *) - (** Divide two Q values *) val div : t -> t -> t + (** Divide two Q values *) - (** Get the numerator of a Q value *) val num_of_q : t -> Z.t + (** Get the numerator of a Q value *) - (** Get the denominator of a Q value *) val den_of_q : t -> Z.t + (** Get the denominator of a Q value *) - (** Convert a Q value to string *) val to_str : t -> string + (** Convert a Q value to string *) - (** Convert a Q value to float *) val to_float : t -> float + (** Convert a Q value to float *) - (** Convert a Q value to showable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert a Q value to json *) end end diff --git a/lib/safemoney.ml b/lib/safemoney.ml index c568e7b..3b7aae2 100644 --- a/lib/safemoney.ml +++ b/lib/safemoney.ml @@ -1,60 +1,13 @@ -open Core +module Discrete = Types.Discrete +module Exchange = Types.Exchange +module Quotient = Types.Quotient +module Predefined = Predefined +module Ops = Ops -(** Exchange type functor *) -module Exchange = Exchange.Make ((Qv : Qv_intf.S)) +let make_q v = Types.make_q v -(** Quotient type functor *) -module Quotient = Quotient.Make ((Qv : Qv_intf.S)) +let make_z v = Types.make_z v -(** Discrete type functor *) -module Discrete = Discrete.Make ((Qv : Qv_intf.S)) ((Zv : Zv_intf.S)) +let qv_to_str s = Types.q_to_str s -(** Signature for user-defined currency type. Typically one needs to provide the following: - - currency symbol - - currency description - - number of named scales with their value if any - - To make custom type module simply implement the Custom signature: - - {[ - module Custome_Type : Custom = struct - let symbol = "CSTM" - let description = "Custom Currency" - - let units = - let table = Hashtbl.create (module String) in - let scale1 = Discrete.Scale.make_scale symbol "scale1" (Utils.make_q "1/1") in - let scale2 = Discrete.Scale.make_scale symbol "scale2" (Utils.make_q "100/1") in - Hashtbl.set table ~key:"scale1" ~data:scale1; - Hashtbl.set table ~key:"scale2" ~data:scale2; - Some table - ;; - - let make_qv qv = Quotient.make_qv (symbol, qv) - - let make_dv unit dv = - match units with - | Some tbl -> - let s = - Option.value_exn ~message:"Error retriving non-existent scale" - @@ Hashtbl.find tbl unit - in - Some (Discrete.make_dv (s, dv)) - | None -> None - ;; - end - ]} *) - -module type Custom = sig - val symbol : string - val description : string - val units : (string, Discrete.Scale.t) Hashtbl.t option - val make_qv : Qv.t -> Quotient.t - val make_dv : string -> Zv.t -> Discrete.t option -end - -(** Convevient helper to make rational Q value *) -let make_q v = Qv.S.make v - -(** Convevient helper to make integer Z value *) -let make_z v = Zv.S.make v +let zv_to_str s = Types.z_to_str s diff --git a/lib/safemoney.mli b/lib/safemoney.mli new file mode 100644 index 0000000..2aacd97 --- /dev/null +++ b/lib/safemoney.mli @@ -0,0 +1,17 @@ +module Discrete = Types.Discrete +module Exchange = Types.Exchange +module Quotient = Types.Quotient +module Predefined = Predefined +module Ops = Ops + +val make_q : string -> Qv.t +(** Helper function to make Qv value *) + +val make_z : string -> Zv.t +(** Helper function to make Zv value *) + +val qv_to_str : Qv.t -> string +(** Helper function to convert Qv to string *) + +val zv_to_str : Zv.t -> string +(** Helper function to convert Zv to string *) diff --git a/lib/types.ml b/lib/types.ml new file mode 100644 index 0000000..4b6dd64 --- /dev/null +++ b/lib/types.ml @@ -0,0 +1,65 @@ +open Base + +(** Exchange type *) +module Exchange = Exchange.Make ((Qv : Qv_intf.S)) + +(** Quotient type *) +module Quotient = Quotient.Make ((Qv : Qv_intf.S)) + +(** Discrete type *) +module Discrete = Discrete.Make ((Qv : Qv_intf.S)) ((Zv : Zv_intf.S)) + +(** Signature for user-defined currency type. Typically one needs to provide the following: + - currency symbol + - currency description + - number of named scales with their value if any + + To make custom type module simply implement the Custom signature: + + {[ + module Custome_Type : Custom = struct + let symbol = "CSTM" + let description = "Custom Currency" + + let units = + let table = Hashtbl.create (module String) in + let scale1 = Discrete.Scale.make_scale symbol "scale1" (Utils.make_q "1/1") in + let scale2 = Discrete.Scale.make_scale symbol "scale2" (Utils.make_q "100/1") in + Hashtbl.set table ~key:"scale1" ~data:scale1; + Hashtbl.set table ~key:"scale2" ~data:scale2; + Some table + ;; + + let make_qv qv = Quotient.make_qv (symbol, qv) + + let make_dv unit dv = + match units with + | Some tbl -> + let s = + Option.value_exn ~message:"Error retriving non-existent scale" + @@ Hashtbl.find tbl unit + in + Some (Discrete.make_dv (s, dv)) + | None -> None + ;; + end + ]} *) +module type Custom = sig + val symbol : string + + val description : string + + val units : (string, Discrete.Scale.t) Hashtbl.t option + + val make_qv : Qv.t -> Quotient.t + + val make_dv : string -> Zv.t -> Discrete.t option +end + +let make_q v = Qv.S.make v + +let make_z v = Zv.S.make v + +let q_to_str s = Qv.S.to_str s + +let z_to_str s = Zv.S.to_str s diff --git a/lib/utils.ml b/lib/utils.ml deleted file mode 100644 index 7416473..0000000 --- a/lib/utils.ml +++ /dev/null @@ -1,284 +0,0 @@ -open Core -open Stdint -open Safemoney - -(** Float round strategies*) -type rounding = - | Up (** decimal digits ignored *) - | Down (** decimal digits ignored *) - | Nearest (** decimal digits ignored *) - | NearestHalfToEven (** decimal digits ignored *) - | TowardsZero (** decimal digits ignored *) - | WithDecimalPrecision (** rounding up to number of decimal digits provided *) - | Truncate (** rounding down to number of decimal digits provided *) - -(** Separator Configuration *) -module Separator : sig - (** {1 Types} *) - type t = private string * string option - - (** Construction*) - val make_exn : char * char option -> t - (** e.g. make_exn (',', Some '.') *) - - (** Get first separator *) - val fst : t -> string - - (** Get second optional separator *) - val snd : t -> string option -end = struct - type t = string * string option - - let make_exn (c1, c2) = - if Char.is_digit c1 || Char.is_whitespace c1 - then failwith "C1 separator type not allowed" - else ( - match c2 with - | Some c2 -> - if Char.compare c1 c2 = 0 - then failwith "Separator must be different as per convention" - else if Char.is_digit c2 || Char.is_whitespace c2 - then failwith "C2 separator type not allowed" - else String.of_char c1, Some (String.of_char c2) - | None -> String.of_char c1, None) - ;; - - let fst x = fst x - let snd x = snd x -end - -(** Printing and rounding configuration *) -type printing_conf = - { separator : Separator.t - ; plus_sign : bool - ; num_of_digits : Uint8.t - ; rounding : rounding - } - -(** Premade separator configuration, e.g. 1000,0 *) -let sep_comma = Separator.make_exn (',', None) - -(** Premade separator configuration, e.g. 1.000,0 *) -let sep_comma_dot = Separator.make_exn (',', Some '.') - -(** Premade separator configuration, e.g. 1_000,0*) -let sep_comma_space = Separator.make_exn (',', Some '_') - -(** Premade separator configuration, e.g. 1000.0 *) -let sep_dot = Separator.make_exn ('.', None) - -(** Premade separator configuration, e.g. 1,000.0 *) -let sep_dot_comma = Separator.make_exn ('.', Some ',') - -(** Premade separator configuration, e.g. 1_000.0 *) -let sep_dot_space = Separator.make_exn ('.', Some '_') - -(** Default printing configuration *) -let default_printing_conf = - { separator = sep_dot - ; plus_sign = false - ; num_of_digits = Uint8.of_int 2 - ; rounding = Up - } -;; - -(** Mark a positive integer value with thousand separator configuration - e.g. [mark_thousands ~v: 1234567 ~sep: ","] - would print "1,234,567" *) -let mark_thousands ~v ~sep = - let k = 1000 in - if Int.compare v k < 0 - then Int.to_string v - else ( - let divmod num den = Int.( / ) num den, Int.rem num den in - let aux ~sep ~i = - match divmod i k with - | 0, 0 -> None - | 0, rem -> Some (Int.to_string rem, 0) - | quo, rem -> - if Int.compare rem 10 < 0 - then Some (sep ^ "0" ^ "0" ^ Int.to_string rem, quo) - else if Int.compare rem 100 < 0 - then Some (sep ^ "0" ^ Int.to_string rem, quo) - else Some (sep ^ Int.to_string rem, quo) - in - Sequence.fold - ~init:"" - ~f:(Fn.flip ( ^ )) - (Sequence.unfold ~init:v ~f:(fun i -> aux ~sep ~i))) -;; - -(** Convert a rational value to string representation of a float value with a printing configuration. - e.g. [let sep_dot_comma = Separator.make_exn ('.', Some ',') in - let printing_conf = { separator = sep_dot_comma; plus_sign = true; num_of_digits = Uint8.of_int 4; rounding = Truncate } in - q_to_decimal ~printing_conf: printing_conf ~qv: (Utils.make_q "-1234567/7")] - would print "-176366.7142" *) -let q_to_decimal ~printing_conf ~qv = - let qv = Qv.S.to_float qv in - let sep1 = Separator.fst printing_conf.separator in - let sep2 = Option.value (Separator.snd printing_conf.separator) ~default:"" in - let num_of_digits = Uint8.to_int printing_conf.num_of_digits in - let modf_aux v = - ( Float.Parts.integral @@ Float.modf v - , Float.abs @@ Float.Parts.fractional @@ Float.modf v ) - in - let sign_aux v = - match Float.sign_exn @@ fst v with - | Sign.Pos -> if printing_conf.plus_sign then "+" else "" - | Sign.Neg -> "-" - | _ -> "" - in - let print_aux v = - let parts = modf_aux v in - let sign = sign_aux parts in - sign - ^ mark_thousands ~v:(Int.abs @@ Float.to_int (fst parts)) ~sep:sep2 - ^ sep1 - ^ Int.to_string - @@ Float.to_int (snd parts) - in - match printing_conf.rounding with - | Up -> print_aux @@ Float.round_up qv - | Down -> print_aux @@ Float.round_down qv - | Nearest -> print_aux @@ Float.round_nearest qv - | NearestHalfToEven -> print_aux @@ Float.round_nearest_half_to_even qv - | TowardsZero -> print_aux @@ Float.round_towards_zero qv - | WithDecimalPrecision -> - let round_decimal ?(decimal_digits = 2) qv = Float.round_decimal ~decimal_digits qv in - print_aux @@ round_decimal ~decimal_digits:num_of_digits qv - | Truncate -> - let fpair = modf_aux qv in - let sign = sign_aux fpair in - let rec aux acc n s : string = if n = 0 then acc else aux (s ^ acc) (n - 1) s in - let pad = aux "" num_of_digits "0" in - let f_part v = - Option.value (List.nth (String.split (Float.to_string v) ~on:'.') 1) ~default:"" - in - let take_digits len v = - let open Angstrom in - match parse_string ~consume:Prefix (take len) v with - | Ok r -> r - | Error _ -> failwith "error parsing digits" - in - (match fpair with - | 0., 0. -> sign ^ "0" ^ sep1 ^ pad - | i, 0. -> - let ipart = mark_thousands ~v:(Int.abs @@ Float.to_int i) ~sep:sep2 in - sign ^ ipart ^ sep1 ^ pad - | i, f -> - let fpart = f_part f in - let ipart = mark_thousands ~v:(Int.abs @@ Float.to_int i) ~sep:sep2 in - let len = num_of_digits - String.length fpart in - let dig = take_digits num_of_digits fpart in - if len > 0 - then sign ^ ipart ^ sep1 ^ dig ^ aux "" len "0" - else sign ^ ipart ^ sep1 ^ dig) -;; - -(** Convert an integer value to float/decimal value of string rep, not used internally but provide mere convenience *) -let z_to_decimal zv = Float.to_string @@ Zv.S.to_float zv - -(** Parse the string representation of a float value with printing configuration - e.g. [ let sep = Separator.make_exn ('.', Some ',') in unsafe_decimal_to_q ~decimal : "+123,456.789"] - would convert value to "123456.789" *) -let unsafe_decimal_to_q ~decimal ~sep = - let sep1 = Separator.fst sep in - let is_eol = function - | '\r' | '\n' -> true - | _ -> false - in - let open Angstrom in - let parser = - lift3 - (fun sign ipart fpart -> - Q.to_string @@ Q.of_float @@ Float.of_string (sign ^ ipart ^ sep1 ^ fpart)) - (peek_char - >>= function - | Some '-' -> advance 1 >>| fun () -> "-" - | Some '+' -> advance 1 >>| fun () -> "" - | Some c when Char.is_digit c -> return "" - | _ -> fail "failure parsing sign") - (match Separator.snd sep with - | None -> take_while1 Char.is_digit - | Some sep2 -> - lift2 - (fun start rest -> start ^ rest) - (count 3 (satisfy Char.is_digit) - <|> count 2 (satisfy Char.is_digit) - <|> count 1 (satisfy Char.is_digit) - >>| String.of_char_list) - (many @@ (char (Char.of_string sep2) *> count 3 (satisfy Char.is_digit)) - >>| List.concat - >>| String.of_char_list)) - ((char (Char.of_string sep1) >>| String.of_char) - *> (take_while1 (fun c -> if Char.is_digit c then true else false) - <* take_till is_eol - <|> (at_end_of_input >>| fun _ -> ""))) - in - parse_string ~consume:All parser decimal -;; - -(** Unsafely convert a float/decimal value of string rep to integer value. - It is unsafe in a sense that the origin of float/decimal is deemed to - be unverified by default and might be as a result of lossy operations. *) -let unsafe_integer_to_z integer = Z.to_string @@ Z.of_int integer - -(** Convert quotient value to the string representaion of a float value with a printing configuration. - This should be used as the final step after all operations have been carried out. *) -let seal_quotient ~printing_conf ~(qv : Quotient.t) = - q_to_decimal ~printing_conf ~qv:qv.value -;; - -(** Convert discrete value to the string representaion of a float value with a printing configuration. - This should be used as the final step after all operations have been carried out. *) -let seal_discrete ~printing_conf ~(dv : Discrete.t) = - let z_to_q = Qv.S.div (make_q (Zv.S.to_str dv.value ^ "/1")) dv.scale.value in - q_to_decimal ~printing_conf ~qv:z_to_q -;; - -(** Convert exchange value to the string representaion of a float value with a printing configuration. - This should be used as the final step after all operations have been carried out. *) -let seal_exchange ~printing_conf ~(xchg : Exchange.t) = - q_to_decimal ~printing_conf ~qv:xchg.value -;; - -(** Convert scale value to the string representaion of a float value with a printing configuration. - This should be used as the final step after all operations have been carried out. *) -let seal_scale ~printing_conf ~(scale : Discrete.Scale.t) = - q_to_decimal ~printing_conf ~qv:scale.value -;; - -(** Unsafely convert a float/decimal value of string rep to quotient value. - It is unsafe in a sense that the origin of float/decimal is deemed to - be unverified by default and might be as a result of lossy operations. *) -let unsafe_float_to_quotient ~symbol ~decimal ~sep = - match unsafe_decimal_to_q ~decimal ~sep with - | Ok qv -> Quotient.make_qv (symbol, make_q qv) - | Error msg -> failwith msg -;; - -(** Unsafely convert a integer value of string rep to discrete value. - It is unsafe in a sense that the origin of the integer is deemed to - be unverified by default and might be as a result of lossy operations. *) -let unsafe_float_to_discrete ~scale ~integer = - let r = unsafe_integer_to_z integer in - Discrete.make_dv (scale, make_z r) -;; - -(** Unsafely convert a float/decimal value of string rep to exchange value. - It is unsafe in a sense that the origin of float/decimal is deemed to - be unverified by default and might be as a result of lossy operations. *) -let unsafe_float_to_exchange ~src ~dst ~decimal ~sep = - match unsafe_decimal_to_q ~decimal ~sep with - | Ok qv -> Exchange.make_xchg ~src ~dst (make_q qv) - | Error msg -> failwith msg -;; - -(** Unsafely convert a float/decimal value of string rep to scale value. - It is unsafe in a sense that the origin of float/decimal is deemed to - be unverified by default and might be as a result of lossy operations. *) -let unsafe_float_to_scale ~symbol ~unit ~decimal ~sep = - match unsafe_decimal_to_q ~decimal ~sep with - | Ok qv -> Discrete.Scale.make_scale symbol unit (make_q qv) - | Error msg -> failwith msg -;; diff --git a/lib/zv.ml b/lib/zv.ml index 0ab6069..386cc42 100644 --- a/lib/zv.ml +++ b/lib/zv.ml @@ -1,21 +1,26 @@ -open Core - type t = Z.t [@@deriving compare] module S = struct - type showable = { value : string } [@@deriving show, sexp, yojson] + type showable = {value: string} [@@deriving show, yojson] let neg x = Z.neg x + let abs x = Z.abs x + let signum x = Z.sign x + let add x y = Z.add x y + let sub x y = Z.sub x y + let mul x y = Z.mul x y + let make str = Z.of_string str + let to_str x = Z.to_string x + let to_float x = Z.to_float x - let to_showable_json x = - Yojson.Safe.to_string @@ showable_to_yojson { value = to_str x } - ;; + let to_json x = + Yojson.Safe.to_string @@ showable_to_yojson {value= to_str x} end diff --git a/lib/zv_intf.ml b/lib/zv_intf.ml index a136b56..c49efd4 100644 --- a/lib/zv_intf.ml +++ b/lib/zv_intf.ml @@ -13,38 +13,38 @@ module type S = sig module S : sig (** {1 Construction} *) val make : string -> t - (** Constructing Z by using a private type, create a Z value from string, e.g. [from_str "123"]. + (** Constructing Z by using a private type to only allow creation from string, e.g. [from_str "123"]. Reason behind is to disallow a range of functions that are unsuitable for currency operations. - For convenience the function alias [make_z] can be used. *) + Helper function [make_z] is provided. *) (** showable for t *) - type showable = { value : string } [@@deriving show, sexp, yojson] + type showable = {value: string} [@@deriving show, yojson] - (** Negate a Z value *) val neg : t -> t + (** Negate a Z value *) - (** Return an absolute Z value *) val abs : t -> t + (** Return an absolute Z value *) - (** Return the sign of Z value, -1, 0, or 1 when the argument is respectively negative, null, or positive. *) val signum : t -> int + (** Return the sign of Z value, -1, 0, or 1 when the argument is respectively negative, null, or positive. *) - (** Add two Z values *) val add : t -> t -> t + (** Add two Z values *) - (** Substract two Z values *) val sub : t -> t -> t + (** Substract two Z values *) - (** Multiply two Z values *) val mul : t -> t -> t + (** Multiply two Z values *) - (** Convert a Z value to string *) val to_str : t -> string + (** Convert a Z value to string *) - (** Convert a Z value to float *) val to_float : t -> float + (** Convert a Z value to float *) - (** Convert a Q value to printable rep *) - val to_showable_json : t -> string + val to_json : t -> string + (** Convert a Z value to json *) end end diff --git a/safemoney.opam b/safemoney.opam index c1b27dc..29fb9fa 100644 --- a/safemoney.opam +++ b/safemoney.opam @@ -10,17 +10,17 @@ doc: "https://gborough.github.io/safemoney/safemoney" bug-reports: "https://github.com/gborough/safemoney/issues" depends: [ "ocaml" {>= "4.14.0"} - "core" + "base" "dune" {>= "3.0"} - "zarith" {>= "1.6"} + "zarith" "stdint" - "angstrom" {>= "0.14.0"} + "angstrom" "re2" "yojson" - "ppx_jane" {>= "v0.16.0"} "ppx_deriving" - "ppx_yojson_conv" "ppx_deriving_yojson" + "ppx_jane" + "ppx_expect" {with-test} "odoc" {with-doc} ] build: [ diff --git a/test/dune b/test/dune index edb7e37..173b592 100644 --- a/test/dune +++ b/test/dune @@ -1,18 +1,6 @@ (library (name safemoney_test) - (libraries - safemoney_lib - base - core - zarith - ppx_expect.common - ppx_expect.config - ppx_expect.config_types - stdint - angstrom - yojson) + (libraries safemoney) (inline_tests) (preprocess - (pps ppx_jane))) - -(include_subdirs unqualified) + (pps ppx_expect))) diff --git a/test/test.ml b/test/test.ml index 917f7b1..5b35f6e 100644 --- a/test/test.ml +++ b/test/test.ml @@ -1,16 +1,15 @@ -open Core -open Stdint -open Safemoney_lib open Safemoney let%expect_test "qv_ops" = let open Quotient in let qv1 = make_qv ("AUD", make_q "3/1") in let qv2 = make_qv ("AUD", make_q "2/1") in - let r = abs (neg (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1")) in - Qv.S.to_str r.value |> print_endline; + let r = + abs + (neg (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1")) + in + qv_to_str r.value |> print_endline ; [%expect {|3/1|}] -;; (* qv_ops_diff_currency *) let () = @@ -19,13 +18,14 @@ let () = let qv1 = make_qv ("AUD", make_q "3/1") in let qv2 = make_qv ("GBP", make_q "2/1") in let _r = - abs (neg (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1")) + abs + (neg + (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1") ) in Printf.printf "%s" "" with | CurrencyTypeMismatch _ -> () | _ -> exit 1 -;; let%expect_test "dv_ops_with_scale" = let open Discrete in @@ -33,9 +33,8 @@ let%expect_test "dv_ops_with_scale" = let dv1 = make_dv (scale, make_z "200") in let dv2 = make_dv (scale, make_z "100") in let r = ( * ) ~t:(dv1 + dv2 - dv2) ~value:(make_z "10") in - Zv.S.to_str r.value |> print_endline; + zv_to_str r.value |> print_endline ; [%expect {|2000|}] -;; (* dv_ops_with_diff_scale *) let () = @@ -50,7 +49,6 @@ let () = with | ScaleTypeMismatch _ -> () | _ -> exit 1 -;; (* non_valid_scale *) let () = @@ -61,30 +59,30 @@ let () = with | Scale.ValidScaleError _ -> () | _ -> exit 1 -;; let%expect_test "xchg_ops" = let open Exchange in let gbp_to_aud = - xchg_recip (xchg_recip (make_xchg ~src:"GBP" ~dst:"AUD" (make_q "8872/4503"))) + xchg_recip + (xchg_recip (make_xchg ~src:"GBP" ~dst:"AUD" (make_q "8872/4503"))) in let aud_to_nzd = make_xchg ~src:"AUD" ~dst:"NZD" (make_q "4908/4503") in let gbp_to_nzd = gbp_to_aud **> aud_to_nzd in - gbp_to_nzd.src |> print_endline; - gbp_to_nzd.dst |> print_endline; - Qv.S.to_str gbp_to_nzd.value |> print_endline; + gbp_to_nzd.src |> print_endline ; + gbp_to_nzd.dst |> print_endline ; + qv_to_str gbp_to_nzd.value |> print_endline ; [%expect {| GBP NZD 14514592/6759003 |}] -;; (* diff_intermediary_symbol *) let () = let open Exchange in try let gbp_to_aud = - xchg_recip (xchg_recip (make_xchg ~src:"GBP" ~dst:"AUD" (make_q "8872/4503"))) + xchg_recip + (xchg_recip (make_xchg ~src:"GBP" ~dst:"AUD" (make_q "8872/4503"))) in let aud_to_nzd = make_xchg ~src:"USD" ~dst:"NZD" (make_q "4908/4503") in let _gbp_to_nzd = gbp_to_aud **> aud_to_nzd in @@ -92,118 +90,92 @@ let () = with | IntermediaryMismatch _ -> () | _ -> exit 1 -;; let%expect_test "predefined" = let open Predefined in let open Quotient in let qv1 = ISO4217_AUD.make_qv (make_q "3/1") in let qv2 = ISO4217_AUD.make_qv (make_q "2/1") in - let dv1 = Core.Option.value_exn (ISO4217_AUD.make_dv "cent" (make_z "200")) in - let dv2 = Core.Option.value_exn (ISO4217_AUD.make_dv "cent" (make_z "100")) in - let rv = abs (neg (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1")) in + let dv1 = Option.get (ISO4217_AUD.make_dv "cent" (make_z "200")) in + let dv2 = Option.get (ISO4217_AUD.make_dv "cent" (make_z "100")) in + let rv = + abs + (neg (( * ) ~t:(qv1 + qv2 - qv2) ~value:(make_q "3/1") / make_q "3/1")) + in let open Discrete in let dv = ( * ) ~t:(dv1 + dv2 - dv2) ~value:(make_z "10") in - Qv.S.to_str rv.value |> print_endline; - Zv.S.to_str dv.value |> print_endline; + qv_to_str rv.value |> print_endline ; + zv_to_str dv.value |> print_endline ; [%expect {| 3/1 2000|}] -;; let%expect_test "mark_thousands" = - Utils.mark_thousands ~v:1234567 ~sep:"," |> print_endline; + Ops.mark_thousands ~v:1234567 ~sep:"," |> print_endline ; [%expect {|1,234,567|}] -;; let%expect_test "qv_to_decimal_up" = - let open Utils in + let open Ops in let printing_conf = - { separator = sep_dot_comma - ; plus_sign = true - ; num_of_digits = Uint8.of_int 4 - ; rounding = Up - } + make_printing_conf ~sep:(sep_dot_comma ()) ~plus_sign:true + ~num_of_digits:4 ~rounding:Up in - q_to_decimal ~printing_conf ~qv:(make_q "-1234567/7") |> print_endline; + q_to_decimal ~printing_conf ~qv:(make_q "-1234567/7") |> print_endline ; [%expect {|-176,366.0|}] -;; let%expect_test "qv_to_decimal_truncate" = - let open Utils in + let open Ops in let printing_conf = - { separator = sep_dot_comma - ; plus_sign = true - ; num_of_digits = Uint8.of_int 4 - ; rounding = Truncate - } + make_printing_conf ~sep:(sep_dot_comma ()) ~plus_sign:true + ~num_of_digits:4 ~rounding:Truncate in - q_to_decimal ~printing_conf ~qv:(make_q "-1234567/7") |> print_endline; + q_to_decimal ~printing_conf ~qv:(make_q "-1234567/7") |> print_endline ; [%expect {|-176,366.7142|}] -;; let%expect_test "decimal_to_qv_pos" = - let open Utils in + let open Ops in let sep = Separator.make_exn ('.', Some ',') in match unsafe_decimal_to_q ~decimal:"+5,050.50" ~sep with - | Ok v -> - v |> print_endline; - [%expect {| 10101/2 |}] + | Ok v -> v |> print_endline ; [%expect {| 10101/2 |}] | Error _ -> () -;; let%expect_test "decimal_to_qv_neg" = - let open Utils in + let open Ops in let sep = Separator.make_exn ('.', Some '_') in match unsafe_decimal_to_q ~decimal:"-5_050.50" ~sep with - | Ok v -> - v |> print_endline; - [%expect {| -10101/2 |}] + | Ok v -> v |> print_endline ; [%expect {| -10101/2 |}] | Error _ -> () -;; let%expect_test "decimal_to_qv_hundreds" = - let open Utils in + let open Ops in let sep = Separator.make_exn ('.', Some ',') in match unsafe_decimal_to_q ~decimal:"-50.50" ~sep with - | Ok v -> - v |> print_endline; - [%expect {| -101/2 |}] + | Ok v -> v |> print_endline ; [%expect {| -101/2 |}] | Error _ -> () -;; let%expect_test "decimal_to_qv_zero" = - let open Utils in + let open Ops in let sep = Separator.make_exn ('.', None) in match unsafe_decimal_to_q ~decimal:"-0.0" ~sep with - | Ok v -> - v |> print_endline; - [%expect {| 0 |}] + | Ok v -> v |> print_endline ; [%expect {| 0 |}] | Error _ -> () -;; let%expect_test "seal_quotient" = - let open Utils in + let open Ops in let open Quotient in let qv = make_qv ("USD", make_q "-1234567/7") in let printing_conf = - { separator = sep_dot_comma - ; plus_sign = true - ; num_of_digits = Uint8.of_int 4 - ; rounding = Truncate - } + make_printing_conf ~sep:(sep_dot_comma ()) ~plus_sign:true + ~num_of_digits:4 ~rounding:Truncate in let r = seal_quotient ~printing_conf ~qv in - r |> print_endline; - [%expect {|-176,366.7142|}] -;; + r |> print_endline ; [%expect {|-176,366.7142|}] let%expect_test "unsafe_float_to_discrete" = - let open Utils in + let open Ops in let open Discrete.Scale in let scale = make_scale "GBP" "Penny" (make_q "100/1") in let r = unsafe_float_to_discrete ~scale ~integer:123 in - Discrete.to_showable_json r |> print_endline; + Discrete.to_json r |> print_endline ; [%expect {|{"discrete_scale":"{\"symbol\":\"GBP\",\"unit\":\"Penny\",\"value\":\"100/1\"}","discrete_value":"{\"value\":\"123\"}"}|}] -;;