# Polymorphic recursion

Is polymorphic recursion avalaible in rescript? If not, the power of GADT is mostly limited to non recursive type.

Yes, but it is one of the cases that requires an explicitly polymorphic type annotation:

``````type rec nested<'a> =
| List(list<'a>)
| Nested(nested<list<'a>>)

let rec depth: 'a. nested<'a> => int = x =>
switch x {
| List(_) => 1
| Nested(n) => 1 + depth(n)
}
``````

Without the `'a.` you 'd get an error

``````This has type: nested<list<'a>>
Somewhere wanted: nested<'a>
The type variable 'a occurs inside list<'a>
``````
2 Likes

Thanks for your answer â€¦ Indeed, my problem is not with polymorphic recursion. Why is the following not working?

``````type rec t<_> = Int : t<int> | Str : t<string>

let f : 'a. (string, t<'a>) => 'a = (s,t) => switch t {
| Int => Belt.Option.getExn(Belt.Int.of_string(s))
| Str => s
}
``````

It is working in OCaml, but if one use `type a.` and not `'a .` to annotate polymorphism (a.k.a. type arguments)

``````type _ t = Int : int t | Str : string t

let f : type a. string * a t -> a = function
| (s,Int) -> int_of_string s
| (s,Str) -> s
``````

Is there a way to have this in ReScript. It is very useful for typed serialisation/deserialisation.

You can use locally abstract types in ReScript, and indeed you should in this case:

``````type rec t<_> = Int: t<int> | Str: t<string>

let f:
type a. (string, t<a>) => a =
(s, t) =>
switch t {
| Int => Belt.Option.getExn(Belt.Int.fromString(s))
| Str => s
}
``````
3 Likes

Thanks!

I tried to guess the syntax. I was probably not far. This feature is to me essential
for serialisation/deserialisation. It allows for sending the description of a data row, then to send
many â€ścompactâ€ť row of the same type that do not need to carry type information.

And by the way: a BNF of rescript somewhere would by nice. I looked in the source of the compiler where there are some BNF elements, but could not find that one.

Cheers,
Christophe

1 Like

If you know OCaml, and it seems you do from your posts, rather than guessing at syntax, you can ask the rescript compiler to convert the OCaml syntax to ReScript syntax for you.

The command `rescript convert Whatever.ml`, will generate `Whatever.res`. Just be aware that it will remove the original file.

2 Likes

Thanks! This indeed could be useful.

Do some people use this? Or is this just intended as a migration tool?

I imagine it is there mainly to help people move off OCaml syntax to ReScript syntaxâ€¦but a maintainer would have to confirm it.

I personally use it just as I mentioned to you, when I forget some ReScript syntax that I know in OCaml.