Search code examples
typesocamlrecordalgebraic-data-types

Does OCaml have record syntax in disjoint unions?


I can write standard disjoint unions like this:

type test = A of int * int | B of int * int;;

However, as the types get more complex, it becomes more and more painful to access a specific field or keep track of what each field represents. Haskell solves this problem with record syntax. That is, it would be nice to able to do something like:

type test = A of {x:int * y:int} | B of {x:int * y:int};;

I can't easily find something like this, but OCaml docs have seemed a bitty spotty in general, so it may well exist. Any suggestions?

EDIT: I'm aware of both disjoint unions and of record syntax, I was just hoping for nice syntax in combining them.


Solution

  • Unfortunately, you cannot put record fields in the arguments of variant constructor declarations. You must define it separately:

    type xy = { x : int; y : int }
    type test = A of xy | B of xy
    

    This is slightly memory inefficient since you need another memory block for xy. Personally I do not mind it if the readability is greatly improved by the record.

    However, I remember there was a proposal and a patch of having a record fields as variant constructors just like you have written:

    type test = A of { x : int; y : int } | B of { x : int; y : int }
    

    which does not require the extra block. But it is not in OCaml 4.01.0, and I am not sure the possibility of availability of this extension in future OCaml releases. Further comments are welcome.