Ocaml 懒惰。来自乐趣和懒惰

Ocaml 懒惰。来自乐趣和懒惰,ocaml,Ocaml,我只是好奇Lazy中的这两个函数 懒散,因为你很有趣 从文档: val from_fun : (unit -> 'a) -> 'a t from_fun f is the same as lazy (f()) but slightly more efficient. 然后我看了看来源 let from_fun (f : unit -> 'arg) = let x = Obj.new_block Obj.lazy_tag 1 in Obj.set_field x 0

我只是好奇
Lazy
中的这两个函数

懒散,因为你很有趣 从文档:

val from_fun : (unit -> 'a) -> 'a t 

from_fun f is the same as lazy (f()) but slightly more efficient.
然后我看了看来源

let from_fun (f : unit -> 'arg) =
  let x = Obj.new_block Obj.lazy_tag 1 in
  Obj.set_field x 0 (Obj.repr f);
  (Obj.obj x : 'arg t)
我猜
Obj
是用来直接为来自_fun的
分配内存的。但它究竟为什么能提高效率呢?或者说
Lazy.from_fun
Lazy(f())
之间有什么区别

偷懒的,从
我真的不明白这些。对我来说,
Lazy.from_val 5
Lazy(5)
都返回具体值为5的
int Lazy.t
。为什么
是懒惰的。from_val
是为了特殊目的?什么样的特殊用途?

我只是猜测:让我们比较一下:

let z1 = lazy (print_newline ())
let z2 = Lazy.from_fun print_newline
使用ocamlc-dlambda

(setglobal Lz!
  (let
    (z1/1008 =
       (makemutable 246
         (function param/1012 (apply (field 31 (global Pervasives!)) 0a)))
     z2/1009 =
       (apply (field 2 (global Lazy!)) (field 31 (global Pervasives!))))
    (makeblock 0 z1/1008 z2/1009)))
z1
是从code
函数param/1012->Pervasives.print_newline()
的函数创建的惰性值,而
z2
是直接从
Pervasives.print_newline
创建的<由于额外的lambda抽象,code>z1可能会稍微低效

正如文档所说,
Lazy.from_val
只是从一个已经计算过的值中创建一个Lazy值,而没有任何暂停。您可以通过尝试
Lazy.from_val(打印字符串“hello”)
Lazy(打印字符串“hello”)
来检查它。前者会立即打印
hello
,但后者不会

(setglobal Lz!
  (let
    (z1/1008 =
       (makemutable 246
         (function param/1012 (apply (field 31 (global Pervasives!)) 0a)))
     z2/1009 =
       (apply (field 2 (global Lazy!)) (field 31 (global Pervasives!))))
    (makeblock 0 z1/1008 z2/1009)))