If you have multiple implementations for the same signature, define your signature inside the compilation block, and not as a compilation block, and (if necessary) the same for modules. Here is an example of this in the standard library: a signature OrderedTypethat describes modules with a type and a comparison function for this type:
module type OrderedType = sig
type t
val compare : t -> t -> int
end
set.mli, map.mli ( Set.OrderedType Map.OrderedType, : ). , (String, Nativeint ..). , : , t compare t -> t -> int, . : Set.Make , OrderedType, .
(* All four modules passed as arguments to Set.Make have the signature Set.OrderedType *)
module IntSet = Set.Make(module type t = int val compare = Pervasives.compare end)
module StringSet = Set.Make(String)
module StringSetSet = Set.Make(StringSet)
module IntSetSet = Set.Make(IntSet)