Making recursive modules convenient

Jane St posted about recursive modules from recursive signatures a while ago.

module rec Even : sig
  type t = Zero | Succ of Odd.t
end = Even
and Odd : sig
  type t = Succ of Even.t
end = Odd

The inconvenience is that you cannot have functions inside recursive modules defined this way.

This is likely obvious to everyone but you can bring the convenience back with just a couple of wrappers!

module rec Even' : sig
  type t = Zero | Succ of Odd.t
end = Even'
and Odd' : sig
  type t = Succ of Even.t
end = Odd'

module Even = struct
  include Even'
  (* put your functions here *)
end

module Odd = struct
  include Odd'
  (* put your functions here *)
end

Are there any drawbacks that I’m missing?

You actually can, but they’re defined by default as exception-raising functions without any warning about missing definitions. You can however redefine them by including the recursive module followed by the actual implementation, all in the original recursive definition.

1 Like