Модуль 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(см.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).
-
module Mutexed: sig .. end
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/api/Lazy.html