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

Глава 12 Расширения языка

13 Узлы расширения

  • 13.1 Встроенные узлы расширения

(Добавлены в OCaml 4.02; инфиксные обозначения для конструкций, отличных от выражений, добавлены в 4.03; инфиксная запись (e1 ;%ext e2) добавлена в 4.04.)

Узлы расширения — это универсальные заполнители в синтаксическом дереве. Проверка типов отклоняет их; они предназначены для «раскрытия» внешними инструментами, такими как преобразователи -ppx.

Узлы расширения используют те же понятия идентификатора и полезной нагрузки, что и атрибуты 12.12.

Первая форма узла расширения используется для «алгебраических» категорий:

extension ::= [% attr-id attr-payload ]
expr ::= ...
∣ extension
typexpr ::= ...
∣ extension
pattern ::= ...
∣ extension
module-expr ::= ...
∣ extension
module-type ::= ...
∣ extension
class-expr ::= ...
∣ extension
class-type ::= ...
∣ extension

Вторая форма узла расширения может использоваться в структурах и сигнатурах как в языке модулей, так и в объектном языке:

item-extension ::= [%% attr-id attr-payload ]
definition ::= ...
∣ item-extension
specification ::= ...
∣ item-extension
class-field-spec ::= ...
∣ item-extension
class-field ::= ...
∣ item-extension

Для узлов расширения доступна инфиксная форма, если полезная нагрузка имеет тот же вид (выражение с выражением, шаблон с шаблоном и т. д.).

Примеры:

let%foo x = 2 in x + 1     === [%foo let x = 2 in x + 1]
begin%foo ... end          === [%foo begin ... end]
x ;%foo 2                  === [%foo x; 2]
module%foo M = ..          === [%%foo module M = ... ]
val%foo x : t              === [%%foo: val x : t]

При использовании этой формы вместе с инфиксным синтаксисом атрибутов считается, что атрибуты относятся к полезной нагрузке:

fun%foo[@bar] x -> x + 1 === [%foo (fun x -> x + 1)[@bar ] ];

Для удобства также доступна сокращённая запись let%foo x in ..., когда узлы расширения используются для реализации операторов связывания (см. 12.23.4).

Кроме того, строки в кавычках {|...|} можно сочетать с узлами расширения для включения фрагментов синтаксиса из других языков. Эти фрагменты могут обрабатываться препроцессором и преобразовываться в код OCaml без необходимости экранировать кавычки. Для них доступна сокращённая синтаксическая запись:

{%%foo|...|}               === [%%foo{|...|}]
let x = {%foo|...|}        === let x = [%foo{|...|}]
let y = {%foo bar|...|bar} === let y = [%foo{bar|...|bar}]

Например, можно использовать {%sql|...|} для представления произвольных инструкций SQL, если у вас есть преобразователь ppx, распознающий расширение %sql.

Обратите внимание, что не следует использовать форму с разделителем-словом, например {sql|...|sql}, чтобы обозначить использование расширения. Действительно, по коду пользователь не может понять, отличается ли семантика этого строкового литерала от ожидаемой. Кроме того, привязка семантики к определённому разделителю ограничивает возможность изменить его, чтобы избежать проблем с экранированием.

13.1 Встроенные узлы расширения

(Добавлены в OCaml 4.03)

Некоторые узлы расширения распознаются самим компилятором:

  • Расширения ocaml.extension_constructor или extension_constructor принимают в качестве полезной нагрузки конструктор расширяемого вариативного типа (см. 12.14) и возвращают слот его конструктора расширения.
    type t = ..
    type t += X of int | Y of string
    let x = [%extension_constructor X]
    let y = [%extension_constructor Y]
    #  x <> y;;
    
    - : bool = true
  • Расширения ocaml.atomic.loc или atomic.loc принимают в качестве полезной нагрузки выражение OCaml, обозначающее атомарную ячейку. Подробнее см. 9.7.2.
« АтрибутыРасширяемые вариативные типы »
Авторское право © 2026 Национальный институт исследований в области информатики и автоматики

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

Spec-Zone.ru

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