I’m confused about how to handle module equalities when building up a hierarchy of functor applications. Here is a shortened version of my situation:
module A = (struct module Asub end : SA) module B = (struct module Bsub end : SB) module C (A:SA) (B:SB) = struct module A = A module B = B ... end module D (A:SA) (B:SB) = struct module C' = C (A) (B) ... end
D is a sort of add-on module providing optional functionality that is sometimes needed. Then I have both an instance of
C and and instance of
D available at top-level:
module Ctop = C (A) (B) module Dtop = D (A) (B)
and I would like to ensure that
Ctop are seen as identical. I tried something along the lines of
module Dtop_ = D (A) (B) module Dtop = (Dtop_ : module type of Dtop_ with module C' = Ctop)
but this is rejected because of missing type equalities in submodules of
C' (at least that’s how I interpret the errors).
How can I handle this situation in an ergonomic way? Or can I restructure the hierarchy in a simpler way?
FWIW, For the functionality in
D I actually only need the values in
C. I made
D a functor of
B only because I don’t have an input signature for a
C argument available: the functor
C is not applied yet with concrete inputs when
D is defined.
[Edit] TL; DR for posterity: The root cause was that in
module F (X:S) : sig module X : S = struct module X = X end
F(X).X.t are not known to be the same type. If
X.t is abstract, they will be incompatible! For this reason, re-exporting input modules from functors requires great care in adding type equalities and is perhaps best avoided!