How to determine the signature of a module whose module implementation is parameterized by a functor

Say I have a module M parameterized by module F :

 module M (F : sig type id type data end) = struct type idtype = F.id type datatype = F.data type component = { id : idtype; data : datatype } let create id data = { id; data } let get_comp_data comp = comp.data let get_comp_id comp = comp.id end 

so i use it like this:

 module F1 = struct type id = int type data = float end module MF1 = M(F1) let comp = MF1.create 2 5.0 let id = MF1.get_comp_id comp 

Now, if I want M match signature S :

 module type S = sig type idtype type datatype type component val create : idtype -> datatype -> component val get_comp_data : component -> datatype val get_comp_id : component -> idtype end module F1 = struct type id = int type data = float end module MF1 = (M(F1) : S) let comp = MF1.create 2 5.0 let id = MF1.get_comp_id comp 

what bothers me, to define get_comp_data and get_comp_id , I need to specify idtype and datatype in module S ; now just imagine that I have other types of records in M with their own types, will I have a dozen types to specify in S ? Is there an easier way to avoid this?

+6
source share
1 answer

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 
+9
source

Source: https://habr.com/ru/post/915439/


All Articles