# Polymorphic variants - automatically deducing lower bound when composing functions

**URL:** <https://discuss.ocaml.org/t/polymorphic-variants-automatically-deducing-lower-bound-when-composing-functions/7311>\
**Category:** Learning\
**Created:** [February 19, 2021, 6:20am UTC](https://discuss.ocaml.org/t/polymorphic-variants-automatically-deducing-lower-bound-when-composing-functions/7311 "2021-02-19T06:20:50Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mbergal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mbergal/32/2705_2.png) [@mbergal](https://discuss.ocaml.org/u/mbergal)\
**Post date:** [February 19, 2021, 6:20am UTC](https://discuss.ocaml.org/t/polymorphic-variants-automatically-deducing-lower-bound-when-composing-functions/7311/1 "2021-02-19T06:20:50Z")

</div>

Compiling

```auto
let f e = match e with 
    | `A -> "a"
let g e = match e with 
    | `B -> "b"
    | _ as e -> f e

```

I get an error:

```auto
Error: This expression has type [> `B] but an expression was expected of type
         [< `A]
       The second variant type does not allow tag(s) `B

```

but this compiles fine

```auto
let g e = match e with 
    | `B -> "b"
    | `A as e -> f e

```

Is there any way to tell the compiler to deduce the type of `_` in the first fragment?

---

<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:** [February 19, 2021, 8:58am UTC](https://discuss.ocaml.org/t/polymorphic-variants-automatically-deducing-lower-bound-when-composing-functions/7311/2 "2021-02-19T08:58:01Z")

</div>

The type of `e` is the same in every branch of the pattern matching, thus in

```ocaml
let g e = match e with 
    | `B -> "b"
    | e2 -> f e2

```

The type of `e2` is `[>`B]`due to the first branch and`f e2` is ill-typed. This one of the limitation of polymorphic variants. Contrarily, in your second example,

```ocaml
let g e = match e with 
    | `B -> "b"
    | `A as e2 -> f e2

```

the variable `e2` as the same type than ``A` and `f e2` is well-typed.  
Note that this solution scales (partially) if you use `#`-types:

```ocaml
type first = [`A | `B | `C]
type second = [`D | `E | `F]
let f = function
  | #first -> 1

let g = function
  | #second -> 2
  | #first as x -> f x

```
