type constant =
Pconst_integer of string * char option
| Pconst_char of int
| Pconst_string of string * string option
| Pconst_float of string * char option
What should be in my .atd file? I tried this ,
type constant = [
Pconst_integer of (string * string option)
| Pconst_char of int
| Pconst_string of (string * string option)
| Pconst_float of (string * string option)
] <ocaml repr="classic">
But then i get this type,
type constant = Person_t.constant =
Pconst_integer of (string * string option)
| Pconst_char of int
| Pconst_string of (string * string option)
| Pconst_float of (string * string option)
which is not same as the one i want. It gives me an error when i try to interchangeably use them. Error message - This variant or record definition does not match that of type. They have different arities.
I believe this is the old issue with syntax for two-argument constructors
A of (int * int option) is a one-argument constructor where the argument is a pair of type int * int option, while A of int * int option is a two-argument constructor; the first argument is int, the second int option. It looks like your .atd file lists one-argument constructors where it should list two-argument constructors.
In the past when I heavily used Atd, I would use the custom wrapper for this. At least for me, my serialization target was JSON I would define my serialization structure in Atd any my types in OCaml when they didn’t match the obvious defaults.
You can’t. The OCaml type generated by atdgen with <ocaml repr="classic"> and with the upcoming atdml by default is:
type constant =
Pconst_integer of (string * char option)
| Pconst_char of int
| Pconst_string of (string * string option)
| Pconst_float of (string * char option)
i.e. each variant takes either zero or one argument as payload.
Classic variants with multiple arguments are not supported because at the time atdgen was created, I considered them a minor performance optimization and polymorphic variants were the default (this was at a time when I thought polymorphic variants were preferable because we didn’t have type-based disambiguation of variant constructors so we couldn’t define multiple types in the same file that would reuse a constructor name).
Now that we have type-based disambiguation of variant constructors and record field names, I find classic variants to be a better choice most of the time. They are the default in atdml. I’m still not sure about the usefulness of supporting variants of multiple arguments or inline records in the context of ATD and JSON serialization. If you or someone else still wants the feature, please explain how it would be helpful to you (performance?) and post a detailed proposal on atd issues so that we can easily implement it.