Spec-Zone.ru › OCaml
☰Язык программирования OCaml
  • Язык программирования OCaml
  • Расширения языка

Глава 12 Расширения языка

14 Типы расширяемых вариантов

  • 14.1 Приватные расширяемые типы вариантов

(Введены в 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

Типы расширяемых вариантов — это типы вариантов, которые можно расширить новыми конструкторами вариантов. Расширяемые типы вариантов определяются с использованием ... Новые конструкторы вариантов добавляются с помощью +=.

module Expr = struct
  type attr = ..

  type attr += Str of string

  type attr +=
    | Int of int
    | Float of float
end

Обработка шаблонов с расширяемым типом варианта требует наличия обработчика по умолчанию для неизвестных конструкторов вариантов:

let to_string = function
  | Expr.Str s -> s
  | Expr.Int i -> Int.to_string i
  | Expr.Float f -> string_of_float f
  | _ -> "?"

Предыдущим примером расширяемого типа варианта является встроенный тип exn, используемый для исключений. Действительно, конструкторы исключений могут быть объявлены с помощью синтаксиса расширения типа:

type exn += Exc of int

Расширяемые конструкторы вариантов могут быть переопределены с другим именем. Это позволяет экспортировать варианты из другого модуля.

# let not_in_scope = Str "Foo";;

Error: Unbound constructor Str
type Expr.attr += Str = Expr.Str
# let now_works = Str "foo";;

val now_works : Expr.attr = Expr.Str "foo"

Расширяемые конструкторы вариантов могут быть объявлены private. Как и в случае с обычными вариантами, это предотвращает их прямое создание с помощью вызова конструктора, но при этом позволяет использовать их в шаблонах сопоставления.

module B : sig
  type Expr.attr += private Bool of int
  val bool : bool -> Expr.attr
end = struct
  type Expr.attr += Bool of int
  let bool p = if p then Bool 1 else Bool 0
end
# let inspection_works = function
    | B.Bool p -> (p = 1)
    | _ -> true;;

val inspection_works : Expr.attr -> bool = 
# let construction_is_forbidden = B.Bool 1;;

Error: Cannot use private constructor Bool to create values of type Expr.attr

14.1 Приватные расширяемые типы вариантов

(Введены в OCaml 4.06)

type-representation ::= ...
∣ = private ..

Расширяемые типы вариантов могут быть объявлены private. Это препятствует прямому объявлению новых конструкторов, но позволяет ссылаться на конструкторы расширения в интерфейсах.

module Msg : sig
  type t = private ..
  module MkConstr (X : sig type t end) : sig
    type t += C of X.t
  end
end = struct
  type t = ..
  module MkConstr (X : sig type t end) = struct
    type t += C of X.t
  end
end
« Элементы расширенияГенеративные функторы »
Авторское право © 2024 Institut National de Recherche en Informatique et en Automatique

© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/extensiblevariants.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API