I was surprised to discover that, in this code, only d fails to compile:
module A = struct type t = V end
module B = A
module C = struct include A end
module D = struct type t = V end
type x = X of A.t
let b = X B.V
let c = X C.V
let d = X D.V
It’s easy to understand that the explicit aliasing of module B = A would make A.t and B.t equivalent, but I expected include A to be something other than aliasing all of the members of B within its scope.
Is there a way to replicate a module without aliasing its members or repeating the module’s implementation (as with D above)?
Maybe this is the wrong way to think of it, but it just occurred to me that providing a module signature actually ends up yielding nominal type constraints…?
This brings to me the opposite question: is there a way to duplicate a module A and keep type equalities with A, while providing a signature?
module A = struct type t = V end
module B : ??? = A
You can specify type equalities manually:
module B : (module type of A with type t = A.t) = A
But you would like them to be derived automatically.
I found this rather absurd method:
module A' = struct include A end
(* this derives a signature with the desired type equalities:
* module A' : sig type t = A.t = V end *)
module B : module type of A' = A