首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OCaml's Lazy.lazy_from_val的目的是什么?

OCaml's Lazy.lazy_from_val的目的是什么?
EN

Stack Overflow用户
提问于 2012-03-18 17:39:54
回答 2查看 351关注 0票数 5

Lazy.lazy_from_val的文档指出,此函数适用于特殊情况:

代码语言:javascript
运行
复制
val lazy_from_val : 'a -> 'a t
  lazy_from_val v returns an already-forced suspension of v This is for special purposes only and should not be confused with lazy (v).

他们说的是什么案子?

如果我根据以下值创建了一对挂起的计算:

代码语言:javascript
运行
复制
let l1 = lazy 123
let l2 = Lazy.lazy_from_val 123

这两者有什么区别呢?因为Lazy.lazy_is_val l1Lazy.lazy_is_val l2都返回,表示值已经是强制的!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-18 18:42:27

特殊的目的是,如果您需要一个延迟值,但有时您有一个已经计算出来的(非惰性)值。可以使用lazy_from_val将已经计算的值转换为值的(强制)延迟版本。

代码语言:javascript
运行
复制
let f lazyint =
    Lazy.force lazyint + 42

let li = lazy 4;;

# f li;;
- : int = 46
# f 14;;
    ^^
Error: This expression has type int but an expression was expected of type
         int Lazy.t = int lazy_t
# f (Lazy.lazy_from_val 14);;
- : int = 56

在这个(人为的)示例中,您可能希望使用一个普通整数值(在本例中为14)调用f。您可以这样做,但您需要使用Lazy.lazy_from_val来使其工作。

关键的区别在于,lazy接受'a类型的表达式,并创建'a lazy_t类型的挂起计算(本质上是闭包)。Lazy.lazy_from_val接受'a类型的预计算值,并将其转换为'a lazy_t类型的(预强制)值。如果该表达式有副作用,则可以看出两者之间的差异。

代码语言:javascript
运行
复制
# let p () = print_string "here\n"; 3 ;;
val p : unit -> int = <fun>
# let l1 = lazy (p ());;
val l1 : int lazy_t = <lazy>
# let l2 = Lazy.lazy_from_val (p ());;
here
val l2 : int Lazy.t = lazy 3
# f l1;;
here
- : int = 45
# f l2;;
- : int = 45
# 

可以使用显式闭包和引用直接实现惰性操作。正如Matthias所指出的,OCaml的惰性机制使用特殊的语法来减少使用它的麻烦。也就是说,lazy是OCaml关键字,而不是函数。

票数 7
EN

Stack Overflow用户

发布于 2012-03-18 17:54:14

lazy_from_val是一个函数,而不是语法。因此,

代码语言:javascript
运行
复制
# let id = fun x -> x;;
val id : 'a -> 'a = <fun>
# Lazy.lazy_is_val (lazy (id 123));;
- : bool = false
# Lazy.lazy_is_val (Lazy.lazy_from_val (id 123));;
- : bool = true
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9760580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档