Extensible variant types とは OCaml の言語拡張のひとつで、後からコンストラクタを拡張できる性質を持ったバリアント型を定義できる。

型を宣言するときは .. を使う

 type color = ..

バリアントに新しいコンストラクタを追加するときは += を使う

type color += Red
type color +=
  | Blue
  | Green
  | Rgb of { r: int; g: int; b: int }

後から型を拡張できる特性から、パターンマッチングでは網羅することができないため、未知のコンストラクタを処理するためのデフォルトケースが必要になっている。Scalaで例えるとsealed無しのMarker Traitみたいな感じか

let string_of_color = function
  | Red -> "red"
  | Blue -> "blue"
  | Green -> "green"
  | Rgb {r; g; b} -> "RGB(" ^ (string_of_int r) ^ ", " ^ (string_of_int g) ^ ", " ^ (string_of_int b) ^ ")"
  | _ -> "unknown"

実は OCaml の例外は Extensible variant types が使われている。utopで確かめてみる

# exception Foo_exception of int;;
# Foo_exception 10;;
- : exn = Foo_exception 10

exn型の定義を見てみるとたしかに .. となっているのが確認できる

# #show exn;;
type exn = ..

参考文献