# Locally abstract type with inline record pattern

**URL:** <https://discuss.ocaml.org/t/locally-abstract-type-with-inline-record-pattern/14225>\
**Category:** Learning\
**Created:** [February 29, 2024, 11:19pm UTC](https://discuss.ocaml.org/t/locally-abstract-type-with-inline-record-pattern/14225 "2024-02-29T23:19:15Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![zbaylin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/zbaylin/32/4047_2.png) [@zbaylin](https://discuss.ocaml.org/u/zbaylin)\
**Post date:** [February 29, 2024, 11:19pm UTC](https://discuss.ocaml.org/t/locally-abstract-type-with-inline-record-pattern/14225/1 "2024-02-29T23:19:16Z")

</div>

A relatively recent edition to the language (I can’t seem to find which version) is locally abstract types in pattern matching.

This looks something like:

```ocaml
type _ spec =
  | Int : int spec
  | String : string spec
  
type t0 = T0 : 'a spec * 'a -> t0
  
let f0 = function
  | T0 (type a) ((spec, v) : a spec * a) -> ()

```

Is it possible to use this syntax/feature with inline record arguments? The following doesn’t work:

```ocaml
type t1 = T1 : { spec : 'a spec; value : 'a } -> t1
  
let f1 = function
  | T1 (type a) { spec : a spec; value : a } -> ()

```

```plaintext
Error: Existential types introduced in a constructor pattern
must be bound by a type constraint on the argument.

```

I recognize that the first example also doesn’t work if you annotate the individual elements of the tuple, but there’s no separate type I can reference here.

I could obviously separate out the record into its own type and annotate `t1` with `[@@unboxed]`, but was curious if it was possible without doing this.

---

<div class="post-metadata">

**Author:** ![mbarbin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mbarbin/32/4421_2.png) [@mbarbin](https://discuss.ocaml.org/u/mbarbin)\
**Post date:** [March 1, 2024, 8:43am UTC](https://discuss.ocaml.org/t/locally-abstract-type-with-inline-record-pattern/14225/2 "2024-03-01T08:43:48Z")

</div>

Hi @zbaylin,

I don’t have an answer to your question, but I’ve encountered a similar situation and found some useful information in this [discussion](https://github.com/ocaml/ocaml/discussions/12935).

Before the current syntax existed, one workaround was to introduce the type in an anonymous `fun` expression and apply it immediately. This approach still works:

```ocaml
# let f1 = function
    | T1 { spec; value } ->
        (fun (type a) (spec : a spec) (value : a) -> ()) spec value
val f1 : t1 -> unit = <fun>

```

Perhaps you’d find this more appealing than separating the record in your example?

I’m also interested in learning about other possible approaches to this issue. Thanks for posting the question!
