9.4 Выражения типов
|
См. также следующие расширения языка: модули первого класса, атрибуты и узлы расширения.
В таблице ниже показаны относительные приоритеты и ассоциативность операторов и неполных конструкций типов. Конструкции с более высоким приоритетом указаны первыми.
| Оператор | Ассоциативность |
| Применение конструктора типа | – |
| # | – |
| * | – |
| -> | справа налево |
| as | – |
Выражения типов обозначают типы в определениях типов данных, а также в ограничениях типов над шаблонами и выражениями.
Переменные типов
Выражение типа ' ident обозначает переменную типа с именем ident. Выражение типа _ обозначает либо анонимную переменную типа, либо анонимные параметры типа. В определениях типов данных переменные типов являются именами параметров типа данных. В ограничениях типов они представляют собой неопределённые типы, которые могут быть проинициализированы любым типом для удовлетворения ограничения типа. В общем случае область видимости именованной переменной типа — вся верхнеуровневая фраза, где она появляется, и она может быть обобщена только при выходе за пределы этой области видимости. Анонимные переменные не имеют такого ограничения. В следующих случаях область видимости именованных переменных типов ограничена выражением типа: 1) для универсальных (явных полиморфных) переменных типа; 2) для переменных типа, которые появляются только в спецификациях публичных методов (поскольку эти переменные будут сделаны универсальными, как описано в разделе 9.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.
Использование #-типов для сокращения полиморфных типов вариантов устарело. Если t — точный тип варианта, то #t преобразуется в [< t], а #t[> `tag1 …`tagk] преобразуется в [< t > `tag1 …`tagk]
Типы вариантов и записей
Нет выражений типа, описывающих (определяющих) типы вариантов и типов записей, поскольку они всегда именованные, т. е. определяются перед использованием и ссылаются по имени. Определения типов описаны в разделе 9.8.1.
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/4.14/htmlman/types.html