Functional programming OCaml惰性评估:';一个懒惰的人vs单位->';A.

Functional programming OCaml惰性评估:';一个懒惰的人vs单位->';A.,functional-programming,ocaml,lazy-evaluation,Functional Programming,Ocaml,Lazy Evaluation,两者都能达到同样的效果 # 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 - : i

两者都能达到同样的效果

# 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
#让x=fun()->开始打印"Hello";一结束;;;
val x:单位->整数=
#x();;
你好
-:int=1
#让y=懒惰开始打印\u结束行“世界”;二结束;;
val y:int lazy\u t=
#懒惰的;懒惰的;;
世界
-:int=2

是否有任何理由认为其中一个应该优先于另一个?哪一个更有效?

首先,它们的行为不同,请尝试再次执行
Lazy.force y
,您会注意到不同之处,不再打印
“World”
消息,因此不会重复计算,因为结果会在Lazy值中记住

这是惰性计算和thunks之间的主要区别。它们都将计算推迟到强制执行时。但是thunk每次都会计算它的主体,其中惰性值将被计算一次,计算结果将被存储


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

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