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

Глава 11 Язык программирования OCaml

10 Типы модулей (описания модулей)

  • 10.1 Простые типы модулей
  • 10.2 Подписи
  • 10.3 Типы функторов
  • 10.4 Оператор with

Типы модулей являются модульными аналогами выражений типов: они определяют общий вид и свойства типов модулей.

тип-модуля ::= путь-к-типу-модуля
∣ sig { описание [;;] } end
∣ functor ( имя-модуля : тип-модуля ) -> тип-модуля
∣ тип-модуля -> тип-модуля
∣ тип-модуля with ограничение-модуля { and ограничение-модуля }
∣ ( тип-модуля )
ограничение-модуля ::= type [параметры-типов] имя-типового-константы уравнение-типов { ограничение-типов }
∣ module путь-к-модулю = расширенный-путь-к-модулю
описание ::= val имя-значения : выражение-типа
∣ external имя-значения : выражение-типа = объявление-внешнего-функции
∣ определение-типа
∣ exception объявление-конструктора
∣ описание-класса
∣ определение-типа-класса
∣ module имя-модуля : тип-модуля
∣ module имя-модуля { ( имя-модуля : тип-модуля ) } : тип-модуля
∣ module type имя-типа-модуля
∣ module type имя-типа-модуля = тип-модуля
∣ open путь-к-модулю
∣ include тип-модуля

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

10.1 Простые типы модулей

Выражение путь-к-типу-модуля эквивалентно типу модуля, связанному с именем путь-к-типу-модуля. Выражение ( тип-модуля ) обозначает тот же тип, что и тип-модуля.

10.2 Подписи

Подписи являются спецификациями типов для структур. Подписи sig … end представляют собой коллекции спецификаций типов для имен значений, имён типов, исключений, имён модулей и имён типов модулей. Структура будет соответствовать подписи, если структура предоставляет определения (реализации) для всех имён, указанных в подписи (и, возможно, больше), и эти определения соответствуют требованиям типов, заданным в подписи.

После каждой спецификации в подписи разрешено необязательное ;;. Оно служит синтаксическим разделителем без семантического значения.

Спецификации значений

Спецификация компонента значения в подписи записывается как val имя-значения : выражение-типа, где имя-значения — имя значения, а выражение-типа — его ожидаемый тип.

Форма external имя-значения : выражение-типа = объявление-внешнего-функции аналогична, за исключением дополнительного требования о реализации в виде внешней функции, указанной в объявление-внешнего-функции (см. главу ‍22).

Спецификации типов

Определение одного или нескольких компонентов типа в сигнатуре записывается как type typedef { and typedef } и состоит из последовательности взаимно рекурсивных определений имён типов.

Каждое определение типа в сигнатуре указывает необязательное уравнение типа = typexpr и необязательное представление типа = constr-decl … или = { field-decl … }. Реализация имени типа в соответствующей структуре должна быть совместима с выражением типа, указанным в уравнении (если задано), и иметь указанное представление (если задано). И наоборот, пользователи этой сигнатуры смогут полагаться на уравнение типа или представление типа, если они заданы. Более точно, у нас есть следующие четыре ситуации:

Абстрактный тип: нет уравнения, нет представления.
‍
Имена, определённые как абстрактные типы в сигнатуре, могут быть реализованы в соответствующей структуре любым типом определения (при условии, что у него одинаковое количество параметров типа). Точная реализация типа будет скрыта от пользователей структуры. В частности, если тип реализован как тип варианта или тип записи, связанные конструкторы и поля не будут доступны пользователям; если тип реализован как сокращение, равенство типов между именем типа и правой частью сокращения будет скрыто от пользователей структуры. Пользователи структуры считают этот тип несовместимым с любым другим типом: был сгенерирован новый тип.
Сокращение типа: уравнение = typexpr, нет представления.
‍
Имя типа должно быть реализовано типом, совместимым с typexpr. Все пользователи структуры знают, что имя типа совместимо с typexpr.
Новый тип варианта или тип записи: нет уравнения, есть представление.
‍
Имя типа должно быть реализовано типом варианта или типом записи с ровно теми конструкторами или полями, которые указаны. Все пользователи структуры имеют доступ к конструкторам или полям и могут использовать их для создания или проверки значений этого типа. Однако пользователи структуры считают этот тип несовместимым с любым другим типом: был сгенерирован новый тип.
Переэкспортированный тип варианта или тип записи: есть уравнение, есть представление.
‍
Этот случай объединяет два предыдущих: представление типа становится видимым для всех пользователей, и новый тип не генерируется.

Спецификация исключения

Спецификация exception constr-decl в сигнатуре требует, чтобы соответствующая структура предоставила исключение с указанным именем и аргументами, и делает исключение доступным для всех пользователей структуры.

Спецификации классов

Спецификация одного или нескольких классов в сигнатуре записывается как class class-spec { and class-spec } и состоит из последовательности взаимно рекурсивных определений имён классов.

Спецификации классов описаны более подробно в разделе ‍11.9.4.

Спецификации типов классов

Спецификация одного или нескольких типов классов в сигнатуре записывается как class type classtype-def { and classtype-def } и состоит из последовательности взаимно рекурсивных определений имён типов классов. Спецификации типов классов описаны более подробно в разделе ‍11.9.5.

Спецификации модулей

Спецификация компонента модуля в сигнатуре записывается как module module-name : module-type, где module-name — имя компонента модуля, а module-type — его ожидаемый тип. Модули могут быть вложены произвольным образом; в частности, функторы могут появляться как компоненты структур, а типы функторов — как компоненты сигнатур.

Для указания компонента модуля, являющегося функтором, можно записать

module module-name ( name1 : module-type1 ) … ( namen : module-typen ) : module-type

вместо

module module-name : functor ( name1 : module-type1 ) -> … -> module-type

Спецификации типов модулей

Компонент типа модуля в сигнатуре может быть задан либо как явный тип модуля, либо как абстрактный тип модуля.

Спецификация абстрактного типа модуля module type modtype-name позволяет имени modtype-name быть реализованным любым типом модуля в соответствующей сигнатуре, но скрывает реализацию типа модуля для всех пользователей сигнатуры.

Спецификация явного типа модуля module type modtype-name = module-type требует, чтобы имя modtype-name было реализовано типом модуля module-type в соответствующей сигнатуре, но делает равенство между modtype-name и module-type очевидным для всех пользователей сигнатуры.

Открытие пути модуля

Выражение open module-path в сигнатуре не определяет никаких компонентов. Оно просто влияет на разбор последующих элементов сигнатуры, позволяя обращаться к компонентам модуля, обозначенному module-path, по их простым именам name вместо доступа по пути module-path . name. Область действия open заканчивается в конце выражения сигнатуры.

Включение сигнатуры

Выражение include module-type в сигнатуре выполняет текстовое включение компонентов сигнатуры, обозначенной module-type. Оно ведёт себя так, как если бы компоненты включённой сигнатуры были скопированы в место include. Аргумент module-type должен ссылаться на тип модуля, который является сигнатурой, а не типом функтора.

10.3 Типы функторов

Выражение типа модуля functor ( module-name : module-type1 ) -> module-type2 — это тип функторов (функций от модулей к модулям), которые принимают в качестве аргумента модуль типа module-type1 и возвращают в качестве результата модуль типа module-type2. Тип модуля module-type2 может использовать имя module-name для обращения к компонентам типа фактического аргумента функтора. Если тип module-type2 не зависит от компонентов типа module-name, выражение типа модуля можно упростить с помощью альтернативной краткой синтаксической записи module-type1 -> module-type2. На тип аргумента функтора не накладываются ограничения; в частности, функтор может принимать в качестве аргумента другой функтор («функтор высшего порядка»).

Когда тип результата модуля сам является функтором,

functor ( name1 : module-type1 ) -> … -> functor ( namen : module-typen ) -> module-type

можно использовать сокращенную форму

functor ( name1 : module-type1 ) … ( namen : module-typen ) -> module-type

10.4 Оператор with

Предполагая, что module-type обозначает сигнатуру, выражение module-type with mod-constraint { and mod-constraint } обозначает ту же сигнатуру, к которой добавлены уравнения типов к некоторым из спецификаций типов, как описано в ограничениях после ключевого слова with. Ограничение type [type-parameters] typeconstr = typexpr добавляет уравнение типа = typexpr к спецификации компонента типа с именем typeconstr ограниченной сигнатуры. Ограничение module module-path = extended-module-path добавляет уравнения типов ко всем компонентам типа подструктуры, обозначаемой module-path, делая их эквивалентными соответствующим компонентам типа структуры, обозначаемой extended-module-path.

Например, если имя типа модуля S связано с сигнатурой

        sig type t module M: (sig type u end) end

то S with type t=int обозначает сигнатуру

        sig type t=int module M: (sig type u end) end

а S with module M = N обозначает сигнатуру

        sig type t module M: (sig type u=N.u end) end

Функтор, принимающий два аргумента типа S, которые делят свой компонент t, записывается как

        functor (A: S) (B: S with type t = A.t) ...

Ограничения добавляются слева направо. После применения каждого ограничения полученная сигнатура должна быть подтипом сигнатуры до применения ограничения. Таким образом, оператор with может только добавлять информацию о компонентах типа сигнатуры, но никогда не удалять информацию.

« КлассыВыражения модулей (реализации модулей) »
Авторские права © 2024 Institut National de Recherche en Informatique et en Automatique

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

Spec-Zone.ru

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