ocamlname-conflict

How to use type with the same name in nested module signature?


It is common practice to name the main type in a module as 't'. I can resolve the type names conflict between nested and container modules at a structure level as follows:

module Container = struct
  type t = A | B
  
  module Nested = struct
    type container_t = t
    type t = C | D

    let f = function
      | A -> C
      | B -> D
  end
end

Also, I can do the same trick at the signature level:

module type CONTAINER = sig
  type t = A | B
  
  module Nested : sig
    type container_t = t
    type t = C | D

    val f : container_t -> t
  end
end

'container_t' helped me to resolve the conflict, but I don't need to keep it visible. Is there any way to hide it? How can I operate with 'CONTAINER.t' and 'Nested.t' in the Nested module signature without producing redundant types?


Solution

  • Local substitutions were introduced to solve this issue in OCaml 4.08. Writing,

      type container_t := t
    

    will introduce a local name container_t for the type t which will not be part of the (external) signature of the module. For instance,

      module Nested : sig
        type container_t := t
        type t = C | D
        val f : container_t -> t
      end
      val u: Nested.container_t
    

    fails with

    Error: Unbound type constructor Nested.container_t