-
- open Batteries
-
- type init_param =
- | Int of int
- | Float of float
-
- module type N = sig
- type t
- val make: init_param -> t
- val add_to_self: t -> t -> unit
- val as_string: t -> string
- end
-
- module Int: N = struct
- type t = int ref
- let make = function
- | Int i -> ref i
- | _ -> invalid_arg "make"
- let add_to_self x y = x := !x + !y
- let as_string = (!) |- Printf.sprintf "%di"
- end
-
- module Float: N = struct
- type t = float ref
- let make = function
- | Float f -> ref f
- | _ -> invalid_arg "make"
- let add_to_self x y = x := !x +. !y
- let as_string = (!) |- Printf.sprintf "%gf"
- end
-
- let parse: string -> (module N) * init_param = fun s ->
- if String.exists s "." then
- (module Float: N), Float (float_of_string s)
- else
- (module Int: N), Int (int_of_string s)
-
- let do_repetitive_work: (module N with type t = 'a) -> 'a -> init_param -> 'a =
- fun (type a) m (x: a) i ->
- let module C = (val m: N with type t = a) in
- let y = C.make i in
- C.add_to_self y x;
- C.add_to_self y (C.make i);
- y
-
- let () = if !Sys.interactive then () else
- let m, i = parse Sys.argv.(1) in
- let module C = (val m: N) in
- let x = C.make i in
- do_repetitive_work (module C: N with type t = C.t) x i
- |> C.as_string
- |> Printf.printf "%s\n"
-