First-Class Modules
Modules can be packed into ordinary values and unpacked at runtime.
Choosing an implementation at runtime:
Using first-class modules with locally abstract types:
module type SHAPE = sig
val name : string
val area : unit -> float
end
let make_circle r = (module struct
let name = "circle"
let area () = Float.pi *. r *. r
end : SHAPE)
let make_square s = (module struct
let name = "square"
let area () = s *. s
end : SHAPE)
let shapes = [ make_circle 1.0; make_square 2.0 ]
let () =
List.iter (fun (module S : SHAPE) ->
Printf.printf "%s: %.2f\n" S.name (S.area ())) shapeslet get_backend = function
| "memory" -> (module Memory_store : STORE)
| _ -> (module File_store : STORE)
let module B = (val get_backend "memory" : STORE) in
B.save "k" "v"let sort_unique (type a) (module O : Set.OrderedType with type t = a) (xs : a list) =
let module S = Set.Make (O) in
S.elements (S.of_list xs)
sort_unique (module Int) [3;1;3;2] (* [1;2;3] *)