How to access identical fields from variant constructors without pattern matching?

If the constructors of two variants share similar fields, how can I write a function that operates on the common ones without having to explicitly pattern match on the variants?

I’m looking to simplify the widerShape method in this snippet (the code is written in Reason):

type rect = {width: int, height: int};
type square = {width: int};
type shape =
  | Rect rect
  | Square square;

let widerShape shape :shape =>
  switch shape {
  | Rect r => Rect {...r, width: r.width + 100}
  | Square s => Square {...s, width: s.width + 100}
  };

Asked a bit too early. Real World OCaml has covered this - move common fields into a parent type. https://realworldocaml.org/v1/en/html/variants.html.

This is my new code:

type rect = {height: int};
type details = 
  | Rect rect
  | Square;
type shape = {width: int, details};

let widerShape shape :shape => {...shape, width: shape.width + 100};

This is not yet documented in RWO, but you can also embed records in variants now, so you can write:

type details = 
  | Rect of { height : int }
  | Square
type shape = {width : int; details : details };

which is ever so slightly more concise, and also a bit more efficient.

I’m not sure what the Reason embedding of that is, though.

4 Likes

That’s nice, thanks. Reason doesn’t seem to support inline records in variants yet. But I’m sure it’ll catch up. :slight_smile:

It depends which OCaml compiler you are using. If you are using 4.03.0 and above, I think you should be able to use this. Ping @SanderSpies If you are using Reason with BuckleScript, BuckleScript compiler still uses 4.02.3 so you have to wait until it upgrades to 4.04

1 Like