The natural way to do this is to seal the module on the definition site, and not on the usage site. Then you just need to express one-time access:
module M (F : sig type id type data end) : S with type idtype = F.id and datatype = F.data = struct ... end
If your functor parameter is more complex, you can also just use the whole module instead of the individual types. For instance:
module type TYPES = sig type id type data (* ...and more... *) end module type S = sig module Types : TYPES type component val create : Types.id -> Types.data -> component val get_comp_data : component -> Types.data val get_comp_id : component -> Types.id end module M (F : TYPES) : S with module Types = F = struct ... end
Or you can even parameterize the signature itself by nesting it in another functor:
module type TYPES = sig type id type data (* ...and more... *) end module S (F : TYPES) = struct module type S = sig type component val create : F.id -> F.data -> component val get_comp_data : component -> F.data val get_comp_id : component -> F.id end end module M (F : TYPES) : S(F).S = struct ... end
source share