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

Глава 11. Язык OCaml

4 Выражения типов

typexpr ::= ' ident
∣ _
∣ ( typexpr )
∣ [[?]label-name:] typexpr -> typexpr
∣ typexpr { * typexpr }+
∣ typeconstr
∣ typexpr typeconstr
∣ ( typexpr { , typexpr } ) typeconstr
∣ typexpr as ' ident
∣ polymorphic-variant-type
∣ < [..] >
∣ < method-type { ; method-type } [; ∣ ; ..] >
∣ # classtype-path
∣ typexpr # class-path
∣ ( typexpr { , typexpr } ) # class-path
poly-typexpr ::= typexpr
∣ { ' ident }+ . typexpr
method-type ::= method-name : poly-typexpr

См. также следующие расширения языка: первоклассные модули, атрибуты, узлы расширения и кортежи с метками.

В таблице ниже показаны относительные приоритеты и ассоциативность операторов и незамкнутых конструкций типов. Конструкции с более высоким приоритетом указаны первыми.

Оператор Ассоциативность
Применение конструктора типа –
# –
* –
-> правая
as –

Выражения типов обозначают типы в определениях типов данных, а также в ограничениях типов для образцов и выражений.

Переменные типов

Выражение типа ' ident обозначает переменную типа с именем ident. Выражение типа _ обозначает либо анонимную переменную типа, либо анонимные параметры типа. В определениях типов данных переменные типов служат именами параметров типа данных. В ограничениях типов они представляют неуказанные типы, которым для выполнения ограничения типа может быть сопоставлен любой тип. В общем случае область видимости именованной переменной типа охватывает всю фразу верхнего уровня, в которой она встречается; обобщить её можно только при выходе из этой области видимости. На анонимные переменные такое ограничение не распространяется. В следующих случаях область видимости именованных переменных типов ограничена выражением типа, в котором они встречаются: 1) для универсальных (явно полиморфных) переменных типов; 2) для переменных типов, встречающихся только в спецификациях открытых методов (поскольку эти переменные становятся универсальными, как описано в разделе 11.9.1); 3) для переменных, используемых в качестве псевдонимов, если тип, для которого они задают псевдоним, недопустим в области видимости охватывающего определения (то есть если он содержит свободные универсальные переменные типов или локально определённые типы).

Типы в скобках

Выражение типа ( typexpr ) обозначает тот же тип, что и typexpr.

Типы функций

Выражение типа typexpr1 -> typexpr2 обозначает тип функций, отображающих аргументы типа typexpr1 в результаты типа typexpr2.

label-name : typexpr1 -> typexpr2 обозначает тот же тип функции, но аргумент имеет метку label.

? label-name : typexpr1 -> typexpr2 обозначает тип функций, отображающих необязательный аргумент с меткой типа typexpr1 в результаты типа typexpr2. Иными словами, физический тип функции будет typexpr1 option -> typexpr2.

Типы кортежей

Выражение типа typexpr1 * … * typexprn обозначает тип кортежей, элементы которых принадлежат соответственно типам typexpr1, … typexprn.

Типы, построенные с помощью конструкторов

Конструкторы типов без параметров, например typeconstr, являются выражениями типов.

Выражение типа typexpr typeconstr, где typeconstr — конструктор типа с одним параметром, обозначает применение унарного конструктора типа typeconstr к типу typexpr.

Выражение типа (typexpr1,…,typexprn) typeconstr, где typeconstr — конструктор типа с n параметрами, обозначает применение n-арного конструктора типа typeconstr к типам от typexpr1 до typexprn.

В выражении типа _ typeconstr анонимное выражение типа _ обозначает анонимные параметры типа и эквивалентно выражению (_, …,_) с числом повторений _, равным арности typeconstr.

Типы с псевдонимами и рекурсивные типы

Выражение типа typexpr as ' ident обозначает тот же тип, что и typexpr, а также связывает переменную типа ident с типом typexpr как внутри typexpr, так и в других типах. В общем случае область видимости псевдонима совпадает с областью видимости именованной переменной типа и охватывает всё окружающее определение. Если переменная типа ident встречается в typexpr, создаётся рекурсивный тип. Рекурсивные типы, для которых существует рекурсивный путь, не содержащий конструктор типа объекта или полиморфного варианта, отклоняются, если не выбран режим -rectypes.

Если ' ident обозначает явную полиморфную переменную, а typexpr обозначает тип объекта или полиморфного варианта, переменная строки в typexpr захватывается переменной ' ident и квантифицируется.

Типы полиморфных вариантов

polymorphic-variant-type ::= [ tag-spec-first { | tag-spec } ]
∣ [> [ tag-spec ] { | tag-spec } ]
∣ [< [|] tag-spec-full { | tag-spec-full } [ > { `tag-name }+ ] ]
tag-spec-first ::= `tag-name [ of typexpr ]
∣ [ typexpr ] | tag-spec
tag-spec ::= `tag-name [ of typexpr ]
∣ typexpr
tag-spec-full ::= `tag-name [ of [&] typexpr { & typexpr } ]
∣ typexpr

Типы полиморфных вариантов описывают значения, которые может принимать полиморфный вариант.

Первый случай — точный тип варианта: известны все возможные теги и связанные с ними типы, и все они могут присутствовать. Его структура полностью известна.

Второй случай — открытый тип варианта, описывающий значение полиморфного варианта: он задаёт список всех тегов, которые может принимать значение, с соответствующими типами. Этот тип по-прежнему совместим с типом варианта, содержащим больше тегов. Особый случай — неизвестный тип, не задающий ни одного тега и совместимый с любым типом варианта.

Третий случай — закрытый тип варианта. Он содержит сведения обо всех возможных тегах и связанных с ними типах, а также о том, какие теги могут присутствовать в значениях. Точный тип варианта (первый случай) — это просто сокращённая запись закрытого типа варианта, в котором присутствуют все возможные теги.

Во всех трёх случаях теги можно задавать непосредственно в форме `tag-name [of typexpr], либо косвенно — через выражение типа, которое должно раскрываться в точный тип варианта; спецификации его тегов подставляются вместо этого выражения.

Полные спецификации тегов вариантов используются только для неточных закрытых типов. Их можно понимать как конъюнктивный тип аргумента: предполагается, что аргумент имеет все типы, перечисленные в спецификации.

Такие конъюнктивные ограничения могут быть невыполнимыми. В этом случае соответствующий тег нельзя использовать в значении данного типа. Это не означает, что весь тип недопустим: можно по-прежнему использовать другие доступные теги. Конъюнктивные ограничения предназначены главным образом для вывода проверки типов. При их использовании в исходных программах неразрешимые ограничения могут приводить к ранним ошибкам.

Типы объектов

Тип объекта < [method-type { ; method-type }] > представляет собой запись типов методов.

Каждый метод может иметь явный полиморфный тип: { ' ident }+ . typexpr. Явные полиморфные переменные имеют локальную область видимости; явный полиморфный тип можно унифицировать только с эквивалентным типом, в котором могут отличаться лишь порядок и имена полиморфных переменных.

Тип < { method-type ; } .. > — это тип объекта, имена и типы методов которого описаны выражениями method-type1, …, method-typen, а также, возможно, некоторыми другими методами, обозначенными многоточием. Это многоточие фактически является особым видом переменной типа (в литературе называемой переменной строки), которая обозначает любое количество дополнительных типов методов.

Типы с #

Тип # classtype-path представляет собой особый вид сокращённой записи. Эта запись унифицируется с типом любого объекта, принадлежащего подклассу типа класса classtype-path. Она обрабатывается особым образом, поскольку обычно скрывает переменную типа (многоточие, обозначающее методы, которые могут быть добавлены в подклассе). В частности, она исчезает, когда многоточие получает конкретное значение. Каждое выражение типа # classtype-path определяет новую переменную типа, поэтому тип # classtype-path -> # classtype-path обычно не совпадает с типом (# classtype-path as ' ident) -> ' ident.

Типы вариантов и записей

Выражений типов, описывающих (определённые) типы вариантов или типы записей, не существует, поскольку у таких типов всегда есть имена: их определяют до использования и обозначают по имени. Определения типов описаны в разделе 11.8.1.

« ИменаКонстанты »
Copyright © 2026 Национальный институт исследований в области информатики и автоматики

© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/types.html

Spec-Zone.ru

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