# Multiple \`with type\`s in first-class module signatures results in confusing error message

**URL:** https://discuss.ocaml.org/t/multiple-with-type-s-in-first-class-module-signatures-results-in-confusing-error-message/17329
**Category:** Learning
**Created:** [September 27, 2025, 12:37pm UTC](https://discuss.ocaml.org/t/multiple-with-type-s-in-first-class-module-signatures-results-in-confusing-error-message/17329 "2025-09-27T12:37:20Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![brendanzab](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brendanzab/32/2927_2.png) [@brendanzab](https://discuss.ocaml.org/u/brendanzab)
#### Post date: [September 27, 2025, 12:37pm UTC](https://discuss.ocaml.org/t/multiple-with-type-s-in-first-class-module-signatures-results-in-confusing-error-message/17329/1 "2025-09-27T12:37:20Z")

</div>

Not sure if I should make a Github issue about this, but today I ended up burning a decent amount of time as a result of a confusing error message. Here’s a simplified example\[1\], which uses multiple `with type` constraints to constrain a first-class module parameter:

```ocaml
module type Graph = sig

  type t
  type vertex

  val empty : t
  val vertex : vertex -> t
  val overlay : t -> t -> t
  val connect : t -> t -> t

end

module Data (V : sig type t end) = struct

  type t =
    | Empty
    | Vertex of V.t
    | Overlay of t * t
    | Connect of t * t

  type vertex = V.t

  let fold (type g) (module G : Graph with type t = g with type vertex = vertex) : t -> g =
    let rec fold = function
      | Empty -> G.empty
      | Vertex x -> G.vertex x
      | Overlay (x, y) -> G.overlay (fold x) (fold y)
      | Connect (x, y) -> G.connect (fold x) (fold y)
    in
    fold

end

```

```plaintext
File "scraps/misc_algebraic_graphs.ml", line 23, characters 32-79:
23 | let fold (type g) (module G : Graph with type t = g with type vertex = vertex) : t -> g =
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Syntax error: invalid package type: only module type identifier and "with type" constraints are supported

```

I thought the error meant either that:

- multiple `with type` constraints were not supported with first-class modules, or
- that constraining it by a concrete type (i.e. `vertex`) ws not supported

I tried working around this limitation by making a new module type that constrained the `vertex` type separately, but it was not an ideal solution:

```ocaml
module Data (V : sig type t end) = struct

  type t =
    | Empty
    | Vertex of V.t
    | Overlay of t * t
    | Connect of t * t

  type vertex = V.t

  module type Graph' = Graph with type vertex = vertex

  let fold (type g) (module G : Graph' with type t = g) : t -> g =
    let rec fold = function
      | Empty -> G.empty
      | Vertex x -> G.vertex x
      | Overlay (x, y) -> G.overlay (fold x) (fold y)
      | Connect (x, y) -> G.connect (fold x) (fold y)
    in
    fold

end

```

This made me wonder why OCaml had such a limitation. I tried searching around the issue tracker and the forum but could not find any information… then several hours after giving up, I stumbled on [this post](https://discuss.ocaml.org/t/typing-limitation-with-first-class-modules-existential-types-and-type-constraints/11261), which used `and type` to add secondary type constraints. Indeed, gong back to the documentation it seems like the grammar of the [`module-type`](https://ocaml.org/manual/5.3/modtypes.html#module-type) and [package-type](https://ocaml.org/manual/5.3/firstclassmodules.html#package-type) non-terminals are subtly different! Is there an important reason for this, or is it an oversight? I.e. why isn’t `package-type` defined as:

```diff
  package-type ::= modtype-path
- ∣ modtype-path with package-constraint { and package-constraint }
+ ∣ package-type with package-constraint { and package-constraint }

```

I think this would be much less surprising, if there’s nothing preventing it. Failing that, it would be nice if the error message could prompt you to use `and type` instead of `with type`. Something like:

```plaintext
Error: Syntax error: invalid package type: secondary "with type" constraints should use the "and type" syntax

```

I think there are probably better ways of presenting such and error - see Rust’s diagnostics, for example, but that’s another issue.

* * *

1. Based on [Algebraic graphs with class (functional pearl)](https://doi.org/10.1145/3122955.3122956)

---

<div class="post-metadata">

### Author: ![kit-ty-kate](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/kit-ty-kate/32/5953_2.png) [@kit-ty-kate](https://discuss.ocaml.org/u/kit-ty-kate)
#### Post date: [September 27, 2025, 1:07pm UTC](https://discuss.ocaml.org/t/multiple-with-type-s-in-first-class-module-signatures-results-in-confusing-error-message/17329/2 "2025-09-27T13:07:29Z")

</div>

Could you open a ticket in the [OCaml bugtracker](https://github.com/ocaml/ocaml/issues)? The proposed syntax error change sounds pretty easy to implement and well defined

---

<div class="post-metadata">

### Author: ![brendanzab](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/brendanzab/32/2927_2.png) [@brendanzab](https://discuss.ocaml.org/u/brendanzab)
#### Post date: [September 27, 2025, 1:57pm UTC](https://discuss.ocaml.org/t/multiple-with-type-s-in-first-class-module-signatures-results-in-confusing-error-message/17329/3 "2025-09-27T13:57:27Z")

</div>

Can do! Was a little intimidated by the issue-creation thing so wanted to be sure 😅

Edit: Posted [here](https://github.com/ocaml/ocaml/issues/14274)
