Если вы собираетесь иметь несколько реализаций для одной и той же подписи, определите свою подпись внутри модуля компиляции, а не как модуль компиляции, и (при необходимости) аналогично для модулей.В стандартной библиотеке есть пример этого: подпись OrderedType
, которая описывает модули с типом и функцией сравнения для этого типа:
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)