With the Signature/Functor pattern, I refer to the style of Map.S
/ Map.Make
in the OCaml standard library. This pattern is highly successful when you want to parameterize a large piece of code over some type without making it fully polymorphic. Basically, you introduce a parameterized module by providing a signature (usually called S
) and a constructor (Make
).
However, when you take a closer look, there is a lot of redundancy in the declaration:
- First, both the signature and the functor have to be announced in the .mli file
- Second, the signature has to be repeated completely in the .ml file (is there actually any legal way to differ from the .mli file here?)
- Finally, the functor itself has to repeat all definitions again to actually implement the module type
Summa summarum, I get 3 definition sites for non-abstract types (e.g. when I want to allow pattern matching). This is completely ridiculous, and thus I assume there is some way around. So my question is two-fold:
- Is there a way to repeat a module type from an .mli file in an .ml file, without having to write it manually? E.g. something like ppx_import for module signatures?
- Is there a way to include a module type in a module inside an .ml file? E.g. when the module type has only one abstract type definition, define that type and just copy the non-abstract ones?