module Lazy: Lazy
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
注意:如果延迟模式在模式匹配的多个情况下出现,则即使在最终由模式匹配选择的 case 之外,也可能会强制执行延迟表达式。在上面的示例中,挂起 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))
。
val is_val : 'a t -> bool
is_val x
如果 x
已经被强制并且没有引发异常,则返回 true
。
val from_val : 'a -> 'a t
from_val v
首先计算 v
(与任何函数一样)并返回其结果的已强制挂起。它与 let x = v in lazy x
相同,但在某些情况下使用动态测试来优化挂起创建。
val map_val : ('a -> 'b) -> 'a t -> 'b t
map_val f x
如果 x
已经被强制,则直接应用 f
,否则其行为与 map f x
相同。
当 x
已经被强制时,此行为可以节省挂起的构造,但另一方面,它会更积极地执行更多工作,如果您从未强制函数结果,则这些工作可能没有用。
如果 f
引发了异常,它将在 is_val x
时立即引发,或者仅在强制 thunk 时引发。
如果 map_val f x
没有引发异常,则 is_val (map_val f x)
等于 is_val x
。
以下定义仅供高级使用;它们需要熟悉延迟编译方案才能正确使用。
val from_fun : (unit -> 'a) -> 'a t
from_fun f
与 lazy (f ())
相同,但效率略高。
仅当函数 f
已定义时才应使用它。特别是,编写 from_fun (fun () -> expr)
始终不如编写 lazy expr
效率高。
val force_val : 'a t -> 'a
force_val x
强制挂起 x
并返回其结果。如果 x
已经被强制,则 force_val x
会再次返回相同的值,而无需重新计算它。
如果 x
的计算引发了异常,则 force_val x
是否引发相同的异常或 Lazy.Undefined
未指定。
x
的强制尝试递归强制 x
本身,则引发 Undefined
。Undefined
(参见 Lazy.Undefined
)。