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
for the primary type of a module.
module Thing : sig type t module Collection : sig type t end val create : string -> t val collect : t list -> Collection.t end
Unfortunately, implementing this is made more painful by the fact that type declarations are recursive by default. If you do the obvious thing:
module Thing = struct type t = string module Collection = struct type t = t list end let create x = x let collect xs = xs 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:
module Thing = struct type t = string module Collection = struct type z = t type t = z list end let create x = x let collect xs = xs end
This works, but it’s ugly and kind of confusing.