# Polymorphic variant type gets restricted when try with is used

**URL:** <https://discuss.ocaml.org/t/polymorphic-variant-type-gets-restricted-when-try-with-is-used/16016>\
**Category:** Learning\
**Tags:** polymorphic-variants\
**Created:** [January 23, 2025, 6:38pm UTC](https://discuss.ocaml.org/t/polymorphic-variant-type-gets-restricted-when-try-with-is-used/16016 "2025-01-23T18:38:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aiono](https://avatars.discourse-cdn.com/v4/letter/a/db5fbb/32.png) [@aiono](https://discuss.ocaml.org/u/aiono)\
**Post date:** [January 23, 2025, 6:38pm UTC](https://discuss.ocaml.org/t/polymorphic-variant-type-gets-restricted-when-try-with-is-used/16016/1 "2025-01-23T18:38:36Z")

</div>

In the following code:

```ocaml
type t = [`A | `B]

let foo : (unit, [> t]) result = failwith "todo"

exception Ex of t

let bar : (unit, [> t]) result =
  try Ok (failwith "todo")
  with Ex t -> Error t

```

type of `bar` is inferred as `(unit, t) result` instead of `(unit, [>t]) result`. Is there a reason for this?

---

<div class="post-metadata">

**Author:** ![deca3](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/deca3/32/6109_2.png) [@deca3](https://discuss.ocaml.org/u/deca3)\
**Post date:** [January 23, 2025, 7:51pm UTC](https://discuss.ocaml.org/t/polymorphic-variant-type-gets-restricted-when-try-with-is-used/16016/2 "2025-01-23T19:51:24Z")

</div>

This is probably normal, because if your exception `Ex` is made to hold a type `t`, then `Error` also recieves a `t`.

If you write `[> t]` it means more than `t`.

For example here `f` can only recieve A or B, but you can see that `g` can recieve more than `t`: it can also recieve C:

```ocaml
type t = [`A | `B]

let f v = (v : t)

let g v = (v : [> t])

g `C ;;

```

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [January 24, 2025, 9:43am UTC](https://discuss.ocaml.org/t/polymorphic-variant-type-gets-restricted-when-try-with-is-used/16016/3 "2025-01-24T09:43:58Z")

</div>

Note that you can get an earlier error by adding an explicit polymorphic annotation

```auto
let bar : 'r. (unit, [> t] as 'r) result =
  try Ok (failwith "todo")
  with Ex t -> Error t

```

will fail with

> ```ocaml
> 5 | with Ex t -> Error t
> ^
> Error: The value t has type t but an expression was expected of type [> t]
> The second variant type is bound to the universal type variable 'a,
> it cannot be closed
> 
> ```

(There is a small regression in the error message there)

If you want to reopen the polymorphic variant types, you can either add an explicit subtyping coercion

```ocaml
let bar :'r. (unit, [> t] as 'r) result =
  try Ok (failwith "todo")
  with Ex t -> Error (t:t:>[> t])

```

or use an `as` pattern over a polymorphic variant pattern:

```ocaml
let bar :'r. (unit, [> t] as 'r) result =
  try Ok (failwith "todo")
  with Ex (#t as e) -> Error e

```

here the `#t` pattern stands expand the type definition `t` into the pattern ` `A|`B` and using an `as` pattern `#t as e` ensure that the type of `e` in the expression side is the most general type that fits the patter `#t`, which is `[> t]` in this case.
