# Pattern match on hlist to functions with first-class module type constrains

**URL:** <https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364>\
**Category:** Learning\
**Created:** [March 24, 2025, 7:36am UTC](https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364 "2025-03-24T07:36:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nico.d](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nico.d/32/5865_2.png) [@nico.d](https://discuss.ocaml.org/u/nico.d)\
**Post date:** [March 24, 2025, 7:36am UTC](https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364/1 "2025-03-24T07:36:46Z")

</div>

Hi,

I tried to adapt the answer of this [post](https://discuss.ocaml.org/t/heterogeneous-lists-difflist-puzzle-functions-versus-pairs/11206) to store first-class module in the list:

```auto
module type S = sig
  type t
end

type _ t =
  | Nil : unit t
  | Cons : (module S with type t = 'a) * 'b t -> ('a -> 'b) t

let rec tofun : type a. a t -> a -> unit =
  function
  | Nil -> fun f -> ()
  | Cons (type b) ( (module C : S with type t = b), xs) ->
      fun f -> tofun xs (f C.t)

```

but I got an error:

```auto
Error: Existential types introduced in a constructor pattern
       must be bound by a type constraint on the argument.

```

I thought it was bound since it is mentioned in the type constraint.

Any help is welcome.

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [March 24, 2025, 8:00am UTC](https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364/2 "2025-03-24T08:00:51Z")

</div>

There are two issues I see with your code:

- `C.t` is a _type_ so it cannot be used as a value in `f C.t`. You may have meant:

- Exstential types introduced by a constructor must be bound by a top-level type constraint, something like

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![nico.d](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nico.d/32/5865_2.png) [@nico.d](https://discuss.ocaml.org/u/nico.d)\
**Post date:** [March 24, 2025, 8:52am UTC](https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364/3 "2025-03-24T08:52:53Z")

</div>

> [@nojb](#):
>
> - `C.t` is a _type_ so it cannot be used as a value in `f C.t`. You may have meant:

Oups!. Very confused about this one. I guess I would have seen after I fixed the first issue.

> [@nojb](#):
>
> - Exstential types introduced by a constructor must be bound by a top-level type constraint, something like
> 
> ```ocaml
> | Cons (type a b) ((module C), xs : (module S with type t = a) * b t) ->
> 
> ```
> 
> instead of
> 
> ```ocaml
> | Cons (type b) ( (module C : S with type t = b), xs) ->
> 
> ```
> 
> should work.

Thank you very much. I was trying to only constraint the first parameter of the Cons constructor whereas the solution was to constraint the pair of parameter.

I added a pair of parenthesis to make clear that the constraint is not only for the second parameter.

> [@nojb](#):
>
> ```ocaml
> | Cons (type a b) ( ( (module C), xs ) : (module S with type t = a) * b t) ->
> 
> ```

Regards,  
Nico

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [March 24, 2025, 9:09am UTC](https://discuss.ocaml.org/t/pattern-match-on-hlist-to-functions-with-first-class-module-type-constrains/16364/4 "2025-03-24T09:09:10Z")

</div>

> [@nico.d](#):
>
> I added a pair of parenthesis to make clear that the constraint is not only for the second parameter.

It is harmless, but not strictly needed either: the type constraint operator `:` binds less strongly than the pair constructor `,`.

Cheers,  
Nicolas
