The following works fine: type foo type bar type _ t = | Foo : string -> foo t | Bar : string -> bar t let to_string : type a . a t -> string = function | Foo x -> x | Bar x -> x However, if you try to avoid the redundant code of the two branches, you get a compile error: let to_string : type a . a t -> string = function | Foo x | Bar x -> x Error: This pattern matches values of type foo t but a pattern was expected which matches values of type a t Type foo is not compatible with type a Is there a real reason for this?