Type signature: enforce subtyping

I’m currently trying to update some of the types in ocaml-zmq (since there is currently some over approximation of types).

type poll_event = In | Out | In_out
type 'a poll_mask = ('a Socket.t * poll_event)

external mask_of : 'a poll_mask array -> t

Essentially what I would optimally like is for the 'a in 'a poll_mask to not necessarily unify with the 'a Socket.t. A common use case for this is below:

let sub: [`Sub] Socket.t = Socket.create Socket.sub in

let req: [`Req] Socket.t = Socket.create Socket.req in

let mask = mask_of [|sub, In; req, In_out|] in

The issue is that currently to type the array as [`Sub | `Req] requires typing both sub and req as such.

What I would optimally like to do is the following, however I don’t know sufficiently about they type system to do it:

type a poll_mask = (a :> b) . (b Socket.t * poll_event)

Such that the type b subtypes a.

Alternatively if anyone has a good reference for polymorphic variants and subtyping that would be greatly appreciated!