Модуль Lazy
module Lazy: sig .. end
Отложенные вычисления.
type 'a t = 'a CamlinternalLazy.t
Значение типа 'a Lazy.t — это отложенное вычисление, называемое приостановкой, с результатом типа 'a. Специальный синтаксис выражения lazy (expr) создаёт приостановку вычисления expr, не вычисляя expr пока. "Принудительное" выполнение приостановки вычислит expr и вернёт его результат. Сопоставление приостановки со специальным синтаксисом шаблона lazy(pattern) также вычислит базовое выражение и попытается привязать его к pattern:
let lazy_option_map f x =
match x with
| lazy (Some x) -> Some (Lazy.force f x)
| _ -> None
Примечание: Если отложенные шаблоны встречаются в нескольких случаях в сопоставлении шаблонов, отложенные выражения могут быть вычислены даже вне случая, выбранного сопоставлением шаблонов. В приведённом выше примере приостановка x всегда вычисляется.
Примечание: lazy_t — встроенный конструктор типов, используемый компилятором для ключевого слова lazy. Не следует использовать его напрямую. Всегда используйте Lazy.t.
Примечание: Lazy.force не является потокобезопасным. Если вы используете этот модуль с несколькими волокнами, systhread или доменами, вам необходимо добавить некоторые блокировки. Однако модуль обеспечивает безопасность памяти, и поэтому одновременный доступ к этому модулю не приведёт к аварийному завершению, но поведение не определено.
Примечание: если программа компилируется с опцией -rectypes, некорректно заданные рекурсивные определения вида let rec x = lazy x или let rec x = lazy(lazy(...(lazy x))) принимаются проверкой типов и, при принудительном вычислении, приводят к некорректным значениям, вызывающим бесконечные циклы в сборщике мусора и других частях выполнения. Без опции -rectypes такие некорректно заданные рекурсивные определения отклоняются проверкой типов.
exception Undefined
Возникает при принудительном вычислении приостановки одновременно из нескольких волокн, systhread или доменов, или когда приостановка пытается принудительно вычислить себя рекурсивно.
val force : 'a t -> 'a
force x принудительно вычисляет приостановку x и возвращает её результат. Если x уже был вычислен, Lazy.force x возвращает то же значение, не перевычисляя его. Если возникло исключение, то это же исключение возникает снова.
-
Возбуждает
Undefined(см.Lazy.Undefined).
Итераторы
val map : ('a -> 'b) -> 'a t -> 'b t
map f x возвращает приостановку, которая при принудительном выполнении вычисляет x и применяет f к её значению.
Эквивалентно lazy (f (Lazy.force x)).
- С 4.13.0
Рассуждения об уже вычисленных приостановках
val is_val : 'a t -> bool
is_val x возвращает true, если x уже был вычислен и не возбудил исключение.
- С 4.00.0
val from_val : 'a -> 'a t
from_val v вычисляет v сначала (как любая функция) и возвращает уже вычисленную приостановку её результата. Это то же, что и let x = v in lazy x, но использует динамические проверки для оптимизации создания приостановок в некоторых случаях.
- С 4.00.0
val map_val : ('a -> 'b) -> 'a t -> 'b t
map_val f x применяет f напрямую, если x уже вычислена, в противном случае она ведёт себя как map f x.
Когда x уже вычислена, это поведение экономит создание приостановки, но с другой стороны выполняет больше работы сразу, что может быть не нужно, если вы никогда не вычисляете результат функции.
Если f вызывает исключение, оно будет вызвано немедленно при is_val x, или вызвано только при принудительном вычислении иначе.
Если map_val f x не вызывает исключение, то is_val (map_val f x) равно is_val x.
- С 4.13.0
Дополнительно
Следующие определения предназначены только для опытных пользователей; для их правильного использования необходимо знание схемы отложенной компиляции.
val from_fun : (unit -> 'a) -> 'a t
from_fun f то же самое, что и lazy (f ()), но немного эффективнее.
Следует использовать только в том случае, если функция f уже определена. В частности, всегда менее эффективно писать from_fun (fun () -> expr) вместо lazy expr.
- С 4.00.0
val force_val : 'a t -> 'a
force_val x принудительно вычисляет приостановку x и возвращает её результат. Если x уже была вычислена, force_val x возвращает то же значение, не перевычисляя его.
Если вычисление x вызывает исключение, не определено, вызовет ли force_val x то же исключение или Lazy.Undefined.
-
Возбуждает
-
Undefinedесли принудительное вычислениеxпытается принудительно вычислитьxрекурсивно. -
Undefined(см.Lazy.Undefined).
-
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/5.0/htmlman/libref/Lazy.html