spacepaste

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