(* TEST expect; *) type 'a t = [< `Foo | `Bar] as 'a;; type 'a s = [< `Foo | `Bar | `Baz > `Bar] as 'a;; type 'a first = First : 'a second -> ('b t as 'a) first and 'a second = Second : ('b s as 'a) second;; type aux = Aux : 'a t second * ('a -> int) -> aux;; let it : 'a. [< `Bar | `Foo > `Bar ] as 'a = `Bar;; let g (Aux(Second, f)) = f it;; [%%expect{| type 'a t = 'a constraint 'a = [< `Bar | `Foo ] type 'a s = 'a constraint 'a = [< `Bar | `Baz | `Foo > `Bar ] type 'a first = First : 'a t second -> ([< `Bar | `Foo ] as 'a) t first and 'a second = Second : [< `Bar | `Baz | `Foo > `Bar ] s second type aux = Aux : ([< `Bar | `Foo ] as 'a) t second * ('a -> int) -> aux val it : [< `Bar | `Foo > `Bar ] = `Bar Line 11, characters 27-29: 11 | let g (Aux(Second, f)) = f it;; ^^ Error: The value "it" has type "[< `Bar | `Foo > `Bar ]" but an expression was expected of type "[< `Bar | `Foo ]" The second variant type is bound to "$a", it may not allow the tag(s) "`Bar" Hint: "$a" is an existential type bound by the constructor "Aux". |}];;