I pasted the wrong code. Slightly less typing is possible by doing "include M" in N's implementation. On Wed, Nov 4, 2015 at 10:22 PM, Ashish Agarwal wrote: > On Wed, Nov 4, 2015 at 9:10 PM, Jacques Garrigue < > garrigue@math.nagoya-u.ac.jp> wrote: > > the code you wrote is exactly equivalent to: >> >> include (((module type of M) with type t = M.t) with type u = M.u) >> > > And the parentheses here don't matter right, so this is the same as: > > include module type of M > with type t = M.t > with type u = M.u > > So then why do we have the "and" syntax at all? > > Well, I can use manifest types to work around this, at the expense of some > manual typing. Here's what works: > > $ cat foo.ml > module M = struct > type t = A | B of u > and u = C of t > end > > module N : sig > type t = M.t = A | B of u > and u = M.u = C of t > val f : t -> t > end = struct > type t = M.t = A | B of u > and u = M.u = C of t > let f x = x > end > > let x : M.t = M.A > let _ = N.f x > >