2016-11-16 19 views
4

都达到同样的事情OCaml的懒评价:“一个lazy_t VS单元 - >”一个

# let x = fun() -> begin print_endline "Hello"; 1 end;; 
val x : unit -> int = <fun> 
# x();; 
Hello 
- : int = 1 
# let y = lazy begin print_endline "World"; 2 end;; 
val y : int lazy_t = <lazy> 
# Lazy.force y;; 
World 
- : int = 2 

没有任何理由一要优于其他?哪一个更有效?

回答

7

首先,它们表现不一样,再次尝试做Lazy.force y,你会注意到不同之处,"World"消息不再被打印,所以计算不会重复,因为结果被记住了在懒惰的价值。

这是懒惰计算和thunk之间的主要区别。他们都推迟计算,直到他们被迫。但是thunk会每次评估它的身体,其中懒惰值将被评估一次,并且计算的结果将被记忆。

在引擎盖下,懒惰值被实现为具有特殊标志的thunk对象。当运行时第一次调用懒惰值时,它会将thunk的主体替换为计算结果。因此,在第一次调用Lazy.force y后,y对象实际上变成了整数2。因此对Lazy.force的后续调用什么也不做。

2

Lazy.force在不重新计算的情况下再次返回相同的值。

为例

let ra = ref 0 ;; 
let y = lazy (ra:= !ra+1);; 
Lazy.force y;; 
# Lazy.force y;; 
- : unit =() 
# !ra;; 
- : int = 1 
# Lazy.force y;; 
- : unit =() 
# !ra;; 
- : int = 1