Re-exporting recursive types

Suppose we have:

module T = struct
  type t = A | B
end

It’s possible to re-export some types with the following syntax:

module M : sig
  type t = T.t = A | B
end = struct
  include T
end

But what if T.t is recursively defined? I can’t seem to get a working syntax. So:

module T = struct
  type x = A of t and t = B of x
end

Re-exporting:

module M : sig
  type t = ??
end = struct
  include T
end

This works for me:

# module T = struct type x = A of t and t = B of x end;;
module T : sig type x = A of t and t = B of x end
# module M : sig type t = T.t type x = T.x end =
   struct
       include T
   end;;
module M : sig type t = T.t type x = T.x end

It seems to be doing what you want.

Not quite… this doesn’t re-export the type constructors in T. For example, T.A ... can be used, but not M.A ..., and I want A to be re-exported in M, like in the non recursive case.

Aha, I see the problem.

Well, I tried this and it seemed to work:

# module N : sig type t = T.t = B of T.x type x = T.x = A of T.t end =
   struct
     include T 
  end;;
module N : sig type t = T.t = B of T.x type x = T.x = A of T.t end

Here are two values of the types:

# let rec x = N.A (y) and y = N.B (x);;
val x : N.x = N.A (T.B <cycle>)
val y : N.t = N.B (T.A <cycle>)
2 Likes

Yes, looks like that’ll work. Wonderful. Thanks :slight_smile: