Глава 11. Язык OCaml
4 Выражения типов
|
См. также следующие расширения языка: первоклассные модули, атрибуты, узлы расширения и кортежи с метками.
В таблице ниже показаны относительные приоритеты и ассоциативность операторов и незамкнутых конструкций типов. Конструкции с более высоким приоритетом указаны первыми.
| Оператор | Ассоциативность |
| Применение конструктора типа | – |
| # | – |
| * | – |
| -> | правая |
| 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 и квантифицируется.
Типы полиморфных вариантов
|
Типы полиморфных вариантов описывают значения, которые может принимать полиморфный вариант.
Первый случай — точный тип варианта: известны все возможные теги и связанные с ними типы, и все они могут присутствовать. Его структура полностью известна.
Второй случай — открытый тип варианта, описывающий значение полиморфного варианта: он задаёт список всех тегов, которые может принимать значение, с соответствующими типами. Этот тип по-прежнему совместим с типом варианта, содержащим больше тегов. Особый случай — неизвестный тип, не задающий ни одного тега и совместимый с любым типом варианта.
Третий случай — закрытый тип варианта. Он содержит сведения обо всех возможных тегах и связанных с ними типах, а также о том, какие теги могут присутствовать в значениях. Точный тип варианта (первый случай) — это просто сокращённая запись закрытого типа варианта, в котором присутствуют все возможные теги.
Во всех трёх случаях теги можно задавать непосредственно в форме `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.
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/types.html