Skip to content

Latest commit

 

History

History
75 lines (52 loc) · 2.18 KB

extensible-variant.mdx

File metadata and controls

75 lines (52 loc) · 2.18 KB
title description canonical
Extensible Variant
Extensible Variants in ReScript
/docs/manual/v11.0.0/extensible-variant

Extensible Variant

Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type even after its initial type declaration. For this, we offer extensible variant types.

Definition and Usage

<CodeTab labels={["ReScript", "JS Output"]}>

type t = ..

type t += Other

type t +=
  | Point(float, float)
  | Line(float, float, float, float)
var Caml_exceptions = require("./stdlib/caml_exceptions.js");

var Other = Caml_exceptions.create("Playground.Other");

var Point = Caml_exceptions.create("Playground.Point");

var Line = Caml_exceptions.create("Playground.Line");

The .. in the type declaration above defines an extensible variant type t. The += operator is then used to add constructors to the given type.

Note: Don't forget the leading type keyword when using the += operator!

Pattern Matching Caveats

Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default _ case for every switch expression.

<CodeTab labels={["ReScript", "JS Output"]}>

let print = v =>
  switch v {
  | Point(x, y) => Console.log2("Point", (x, y))
  | Line(ax, ay, bx, by) => Console.log2("Line", (ax, ay, bx, by))
  | Other
  | _ => Console.log("Other")
  }
function print(v) {
  if (v.RE_EXN_ID === Point) {
    console.log("Point", [v._1, v._2]);
  } else if (v.RE_EXN_ID === Line) {
    console.log("Line", [v._1, v._2, v._3, v._4]);
  } else {
    console.log("Other");
  } 
}

Tips & Tricks

Fun fact: In ReScript, exceptions are actually extensible variants under the hood, so exception UserError(string) is equivalent to type exn += UserError(string). It's one of the very few use-case where extensible variants make sense.

We usually recommend sticking with common variants as much as possible to reap the benefits of exhaustive pattern matching.