Ocaml “Lazy.force”和“Lazy.force”的区别`

Ocaml “Lazy.force”和“Lazy.force”的区别`,ocaml,lazy-evaluation,Ocaml,Lazy Evaluation,惰性模块中有两种力: val force:'a t->'a 力x强制悬架x并返回其结果。如果x有 已被强制,Lazy.force x将再次返回相同的值,而不带 重新计算它。如果引发了异常,则会引发相同的异常 再次提出。如果强制x尝试强制x,则引发未定义 它自己是递归的 val force_val:'a t->'a force_val x强制执行悬架x并返回其结果。如果x有 已被强制,force_val x再次返回相同的值,而不带 重新计算它。如果强制x尝试强制x,则引发未定义 它自己是递归的

惰性模块中有两种力:


val force:'a t->'a

力x强制悬架x并返回其结果。如果x有 已被强制,Lazy.force x将再次返回相同的值,而不带 重新计算它。如果引发了异常,则会引发相同的异常 再次提出。如果强制x尝试强制x,则引发未定义 它自己是递归的


val force_val:'a t->'a

force_val x强制执行悬架x并返回其结果。如果x有 已被强制,force_val x再次返回相同的值,而不带 重新计算它。如果强制x尝试强制x,则引发未定义 它自己是递归的。如果x的计算引发异常,则为 未指定force_val x是否引发相同的异常或 未定义


看来唯一的区别是

如果x的计算引发异常,则为 未指定force_val x是否引发相同的异常或 未定义`

据我所知,如果我们使用
force_val
,我们不知道它是否会引发原始异常或
Undefined


那么这背后的意义是什么?为什么要这样做?我们能从force_val获得什么好处?

我想这是出于性能目的。 如果您希望得到相同的错误,请使用
force
。如果您不想获得更好的性能,请使用
force\u val

正如您所看到的,
force
force_val
做的事情相同,但在发生异常时执行对内存的额外访问

阅读源代码并运行一些测试后,这两个函数的行为似乎与文档中所说的不同:如果只使用
force
,您将始终获得原始错误,但如果使用
force\u val
第一次调用将引发原始异常,对
force\u val
force
的所有后续调用将引发
未定义的


编辑:事实上,我不确定使用
force\u val
而不是
force
是否能提高性能,因为
force
是一个基本元素,而
force\u val
不是。

在我对源代码和实验进行研究之后,让我进一步澄清。基本上,
force\u val
不会将异常存储到lazy变量。第一次force\u val时,它将允许抛出任何异常,从第二次开始,它将只抛出
未定义的
<代码>强制
不同,因为它存储原始异常,并且总是抛出与存储时相同的异常。您所做的实验是因为您首先运行
force_val
,因为它从不存储异常,所以lazy var的exn分支总是未定义的。因此,在同一个惰性变量上调用
force
之后,它将始终引发
Undefined
。如果文档与代码中指定的实际行为不同,是否应该有人提请开发团队注意?