8.15 Extensible variant types

(Introduced in OCaml 4.02)

type-representation::=
= ..
specification::=
type [type-params] typeconstr type-extension-spec
definition::=
type [type-params] typeconstr type-extension-def
type-extension-spec::= += [private] [|] constr-decl { | constr-decl }
type-extension-def::= += [private] [|] constr-def { | constr-def }
constr-def::=constr-decl
constr-name = constr

Extensible variant types are variant types which can be extended withnew variant constructors. Extensible variant types are defined using… New variant constructors are added using +=.

  1. module Expr = struct
  2. type attr = ..
  3. type attr += Str of string
  4. type attr +=
  5. | Int of int
  6. | Float of float
  7. end
  8.  

Pattern matching on an extensible variant type requires a default caseto handle unknown variant constructors:

  1. let to_string = function
  2. | Expr.Str s -> s
  3. | Expr.Int i -> Int.to_string i
  4. | Expr.Float f -> string_of_float f
  5. | _ -> "?"
  6.  

A preexisting example of an extensible variant type is the built-inexn type used for exceptions. Indeed, exception constructors can bedeclared using the type extension syntax:

  1. type exn += Exc of int
  2.  

Extensible variant constructors can be rebound to a different name. Thisallows exporting variants from another module.

  1. let not_in_scope = Str "Foo";;
  2. Error: Unbound constructor Str
  1. type Expr.attr += Str = Expr.Str
  2.  
  1. let now_works = Str "foo";;
  2. val now_works : Expr.attr = Expr.Str "foo"

Extensible variant constructors can be declared private. As withregular variants, this prevents them from being constructed directly byconstructor application while still allowing them to be de-structured inpattern-matching.

  1. module B : sig
  2. type Expr.attr += private Bool of int
  3. val bool : bool -> Expr.attr
  4. end = struct
  5. type Expr.attr += Bool of int
  6. let bool p = if p then Bool 1 else Bool 0
  7. end
  8.  
  1. let inspection_works = function
  2. | B.Bool p -> (p = 1)
  3. | _ -> true;;
  4. val inspection_works : Expr.attr -> bool = <fun>
  1. let construction_is_forbidden = B.Bool 1;;
  2. Error: Cannot create values of the private type Expr.attr

8.15.1 Private extensible variant types

(Introduced in OCaml 4.06)

type-representation::=
= private ..

Extensible variant types can be declared private. This prevents newconstructors from being declared directly, but allows extensionconstructors to be referred to in interfaces.

  1. module Msg : sig
  2. type t = private ..
  3. module MkConstr (X : sig type t end) : sig
  4. type t += C of X.t
  5. end
  6. end = struct
  7. type t = ..
  8. module MkConstr (X : sig type t end) = struct
  9. type t += C of X.t
  10. end
  11. end
  12.