I am experimenting with the module language of OCaml (3.12.1), defining functors and signatures for modules and so on, mostly following the examples from Chapter 2 of the OC
If you look at the inferred signature when you don't write something explicitly:
# module IntType = struct type t = int end ;;
module IntType : sig type t = int end
The signature exposes that t is an int. Your signature, on the contrary:
# module IntType : SOMETYPE = struct type t = int end ;;
module IntType : SOMETYPE
is really:
# module IntType : sig type t end = struct type t = int end ;;
module IntType : sig type t end
This seems to solve your problem:
# module IntType : (SOMETYPE with type t = int) = struct type t = int end ;;
module IntType : sig type t = int end
# module IdentityInt = Identity(IntType) ;;
module IdentityInt : sig val f : IntType.t -> IntType.t end
# IdentityInt.f 0 ;;
- : IntType.t = 0
(you don't need the parens, but they help mentally parse). Basically, you expose the fact that t is an int with your signature. So that OCaml knows the equality IntType.t = int.
For more details of the internals, I'll leave it to more knowledgeable people.