module Lazy: Lazy
type'a
t ='a CamlinternalLazy.t
類型為 'a Lazy.t
的值是一種延遲計算,稱為暫停 (suspension),其結果類型為 'a
。特殊的表達式語法 lazy (expr)
會建立 expr
計算的暫停,但不會立即計算 expr
本身。 「強制執行 (Forcing)」暫停將會計算 expr
並傳回其結果。使用特殊模式語法 lazy(pattern)
比對暫停也會計算底層表達式,並嘗試將其綁定到 pattern
。
let lazy_option_map f x =
match x with
| lazy (Some x) -> Some (Lazy.force f x)
| _ -> None
注意:如果 lazy 模式出現在模式匹配的多個 case 中,即使在模式匹配最終選擇的 case 之外,lazy 表達式也可能被強制執行。在上面的範例中,暫停 x
總是會被計算。
注意:lazy_t
是編譯器用於 lazy
關鍵字的內建類型建構子。您不應直接使用它。請始終使用 Lazy.t
來代替。
注意:Lazy.force
不是並行安全的。如果您在多個纖程 (fiber)、系統執行緒 (systhread) 或網域 (domain) 中使用此模組,則需要新增一些鎖定。但是,該模組可確保記憶體安全,因此,並行存取此模組不會導致當機,但行為是未指定的。
注意:如果程式使用 -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
已被強制執行時,此行為會節省暫停的建構,但另一方面,它會執行更多可能無用的 eager 工作,如果您從不強制執行函式結果的話。
如果 f
引發例外,當 is_val x
時將立即引發該例外,否則只會在強制執行 thunk 時引發。
如果 map_val f x
未引發例外,則 is_val (map_val f x)
等於 is_val x
。
以下定義僅適用於進階用途;它們需要熟悉 lazy 編譯方案才能適當使用。
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
)。