Глава 12 Расширения языка
13 Узлы расширения
(Добавлены в OCaml 4.02; инфиксные обозначения для конструкций, отличных от выражений, добавлены в 4.03; инфиксная запись (e1 ;%ext e2) добавлена в 4.04.)
Узлы расширения — это универсальные заполнители в синтаксическом дереве. Проверка типов отклоняет их; они предназначены для «раскрытия» внешними инструментами, такими как преобразователи -ppx.
Узлы расширения используют те же понятия идентификатора и полезной нагрузки, что и атрибуты 12.12.
Первая форма узла расширения используется для «алгебраических» категорий:
|
Вторая форма узла расширения может использоваться в структурах и сигнатурах как в языке модулей, так и в объектном языке:
|
Для узлов расширения доступна инфиксная форма, если полезная нагрузка имеет тот же вид (выражение с выражением, шаблон с шаблоном и т. д.).
Примеры:
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.
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/extensionnodes.html