spacepaste

  1.  
  2. open Batteries
  3. type init_param =
  4. | Int of int
  5. | Float of float
  6. module type N = sig
  7. type t
  8. val make: init_param -> t
  9. val add_to_self: t -> t -> unit
  10. val as_string: t -> string
  11. end
  12. module Int: N = struct
  13. type t = int ref
  14. let make = function
  15. | Int i -> ref i
  16. | _ -> invalid_arg "make"
  17. let add_to_self x y = x := !x + !y
  18. let as_string = (!) |- Printf.sprintf "%di"
  19. end
  20. module Float: N = struct
  21. type t = float ref
  22. let make = function
  23. | Float f -> ref f
  24. | _ -> invalid_arg "make"
  25. let add_to_self x y = x := !x +. !y
  26. let as_string = (!) |- Printf.sprintf "%gf"
  27. end
  28. let parse: string -> (module N) * init_param = fun s ->
  29. if String.exists s "." then
  30. (module Float: N), Float (float_of_string s)
  31. else
  32. (module Int: N), Int (int_of_string s)
  33. let do_repetitive_work: (module N with type t = 'a) -> 'a -> init_param -> 'a =
  34. fun (type a) m (x: a) i ->
  35. let module C = (val m: N with type t = a) in
  36. let y = C.make i in
  37. C.add_to_self y x;
  38. C.add_to_self y (C.make i);
  39. y
  40. let () = if !Sys.interactive then () else
  41. let m, i = parse Sys.argv.(1) in
  42. let module C = (val m: N) in
  43. let x = C.make i in
  44. do_repetitive_work (module C: N with type t = C.t) x i
  45. |> C.as_string
  46. |> Printf.printf "%s\n"
  47.