Модуль 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 не является потокобезопасным. Если вы используете этот модуль в многопоточной программе, вам необходимо добавить блокировки.
Примечание: если программа скомпилирована с опцией -rectypes, некорректные рекурсивные определения вида let rec x = lazy x или let rec x = lazy(lazy(...(lazy x))) принимаются проверкой типов и приводят, при принудительном выполнении, к некорректным значениям, которые вызывают бесконечные циклы в сборщике мусора и других частях выполнения системы. Без опции -rectypes, такие некорректные рекурсивные определения отклоняются проверкой типов.
exception Undefined
val force : 'a t -> 'a
force x принудительно выполняет приостановку x и возвращает её результат. Если x уже была выполнена, Lazy.force x возвращает то же значение снова без повторного вычисления. Если при этом возникло исключение, то же исключение возникает снова.
-
Возбуждает
Undefinedесли принудительное выполнениеxпытается рекурсивно выполнитьx.
Итераторы
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.
Устаревшее
val lazy_from_fun : (unit -> 'a) -> 'a t
from_fun.val lazy_from_val : 'a -> 'a t
from_val.val lazy_is_val : 'a t -> bool
is_val.
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/4.14/htmlman/libref/Lazy.html