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