Глава 12. Расширения языка
1 Рекурсивные определения значений
(Добавлено в Objective Caml 1.00)
Как упоминалось в разделе 11.7.2, конструкция связывания let rec помимо определения рекурсивных функций также поддерживает некоторый класс рекурсивных определений нефункциональных значений, например
которая связывает name1 с циклическим списком 1::2::1::2::…, а name2 — с циклическим списком 2::1::2::1::… Неформально говоря, принимаемый класс определений состоит из определений, в которых определяемые имена встречаются только внутри тел функций или в качестве аргументов конструктора данных.
Точнее, рассмотрим выражение:
Оно будет принято, если каждое из выражений expr1 … exprn является статически конструктивным относительно name1 … namen, не связано непосредственно ни с одним из name1 … namen и не является конструктором массива, аргументы которого имеют абстрактный тип.
Выражение e называется статически конструктивным относительно переменных name1 … namen, если выполняется хотя бы одно из следующих условий:
- e не содержит свободных вхождений ни одного из name1 … namen
- e является переменной
- e имеет форму fun … -> …
- e имеет форму function … -> …
- e имеет форму lazy ( … )
-
e имеет одну из следующих форм, где каждое из выражений expr1 … exprm является статически конструктивным относительно name1 … namen, а expr0 является статически конструктивным относительно name1 … namen, xname1 … xnamem:
- let [rec] xname1 = expr1 and … and xnamem = exprm in expr0
- let module … in expr1
- constr (expr1, … , exprm)
- `tag-name (expr1, … , exprm)
- [| expr1; … ; exprm |]
- { field1 = expr1; … ; fieldm = exprm }
- { expr1 with field2 = expr2; … ; fieldm = exprm } где expr1 не связано непосредственно с name1 … namen
- ( expr1, … , exprm )
- expr1; … ; exprm
Выражение e называется непосредственно связанным с переменной name в следующих случаях:
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/letrecvalues.html