Unlike let declarations, type declarations in OCaml are automatically recursive. This seems harmless at first, but it actually causes more trouble than it's worth. To see why, let's look at an example. Here's a simple signature that uses nested modules and that adopts the reasonable convention of using t for the primary type of a module.

  1. module Thing : sig
  2. type t
  3.  
  4. module Collection : sig
  5. type t
  6. end
  7.  
  8. val create : string -> t
  9. val collect : t list -> Collection.t
  10. end

Unfortunately, implementing this is made more painful by the fact that type declarations are recursive by default. If you do the obvious thing:

  1. module Thing = struct
  2. type t = string
  3.  
  4. module Collection = struct
  5. type t = t list
  6. end
  7.  
  8. let create x = x
  9. let collect xs = xs
  10. end

You get the following error:

File "type_is_implicitly_rec.ml", line 5, characters 9-20:
The type abbreviation t is cyclic

You can fix this by introducing an extra dummy type definition in between to break the recursion:

  1. module Thing = struct
  2. type t = string
  3.  
  4. module Collection = struct
  5. type z = t
  6. type t = z list
  7. end
  8.  
  9. let create x = x
  10. let collect xs = xs
  11. end

This works, but it's ugly and kind of confusing.