Глава 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. Явные полиморфные переменные имеют локальную область видимости, и явный полиморфный тип может быть унифицирован только с эквивалентным, где могут изменяться только порядок и имена полиморфных переменных.
Тип < { метод-тип ; } .. > — это тип объекта, чьи имена и типы методов описываются метод-тип1, …, метод-типn, и, возможно, ещё некоторыми другими методами, представленными многоточием. Это многоточие фактически является особым видом параметра типа (называемым параметром-строкой в литературе), обозначающим любое количество дополнительных типов методов.
#-типы
Тип # путь-к-классу — это особый вид сокращения. Это сокращение унифицируется с типом любого объекта, принадлежащего подклассу класса типа путь-к-классу. Оно обрабатывается особым образом, так как обычно скрывает параметр типа (многоточие, представляющее методы, которые могут быть добавлены в подклассе). В частности, оно исчезает, когда многоточие подставляется. Каждый выражение типа # путь-к-классу определяет новый параметр типа, поэтому тип # путь-к-классу -> # путь-к-классу обычно не совпадает с типом (# путь-к-классу as ' идентификатор) -> ' идентификатор.
Типы вариантов и записей
Нет выражений типа, описывающих (определяющих) типы вариантов или записей, так как они всегда именованные, т.е. определены до использования и к ним обращаются по имени. Определения типов описаны в разделе 11.8.1.
© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/types.html