(* Valeurs monétaires *)

module type MONEY = sig
  type t = private { i : int; f : int }
  val create : int -> int -> t
  val add : t -> t -> t
end

(* Il est pratique d'introduire une fonction valeur qui calcule la valeur
   représentée par (i, f) en tenant compte du caractère signé de i *)
let value i f = if i < 0 then 100 * i - f else 100 * i + f

module Money = struct

  type t = { i : int; f : int }

  let create i f =
    if f < 0 || f >= 100 then invalid_arg "create";
    { i = i; f = f }

  let add x y =
    let v = value x.i x.f + value y.i y.f in
    { i = v / 100; f = abs v mod 100 }

end

module Euro : MONEY = Money
module Dollar : MONEY = Money

(* Note : Bien que les deux modules Euro et Dollar sont tous deux définis
   comme étant égaux au module Money, les deux types Euro.t et Dollar.t
   sont néanmoins distincts. C'est l'interface explicite ": MONEY" qui
   cache la représentation du type t dans les modules Euro et Dollar. *)

let euros_to_dollars ch eur =
  let cents = truncate (ch *. float (value eur.Euro.i eur.Euro.f)) in
  Dollar.create (cents / 100) (abs cents mod 100)


This document was generated using caml2html