Модуль 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 не является потокобезопасным. Если вы используете этот модуль с несколькими волокнами, systhreads или областями, вам потребуется добавить некоторые блокировки. Однако модуль гарантирует безопасность памяти, и поэтому одновременный доступ к этому модулю не приведёт к аварии, но поведение не определено.
Примечание: если программа скомпилирована с опцией -rectypes, некорректно заданные рекурсивные определения вида let rec x = lazy x или let rec x = lazy(lazy(...(lazy x))) принимаются проверяющим типы и приводят при принудительном выполнении к некорректным значениям, которые вызывают бесконечные циклы в сборщике мусора и других частях среды выполнения. Без опции -rectypes такие некорректно заданные рекурсивные определения отклоняются проверяющим типы.
exception Undefined
Выбрасывается при принудительном выполнении приостановки одновременно из нескольких волокн, systhreads или областей, или когда приостановка пытается принудительно выполнить себя рекурсивно.
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
Рассмотрение уже принудительно выполненных приостановок
val is_val : 'a t -> bool
is_val x возвращает true, если x уже выполнена и не вызвала исключение.
- С 4.00
val from_val : 'a -> 'a t
from_val v оценивает v первой (как это делает любая функция) и возвращает уже принудительно выполненную приостановку её результата. Это то же, что и let x = v in lazy x, но использует динамические проверки для оптимизации создания приостановок в некоторых случаях.
- С 4.00
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
Дополнительно
Следующие определения предназначены только для продвинутых пользователей; для их правильного использования требуется знание схемы отложенной компиляции.
val from_fun : (unit -> 'a) -> 'a t
from_fun f — то же самое, что и lazy (f ()), но немного более эффективное.
Следует использовать только в том случае, если функция f уже определена. В частности, всегда менее эффективно писать from_fun (fun () -> expr) , чем lazy expr.
- С 4.00
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-2024 INRIA.
https://ocaml.org/manual/5.2/api/Lazy.html