Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OCaml'的目的是什么;他是懒惰的?_Ocaml_Lazy Evaluation - Fatal编程技术网

OCaml'的目的是什么;他是懒惰的?

OCaml'的目的是什么;他是懒惰的?,ocaml,lazy-evaluation,Ocaml,Lazy Evaluation,来自_val的Lazy.Lazy_文件声明此函数用于特殊情况: 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). 他们在谈论哪些案例 如果我从如下值创建一对挂起的计算: let l1 = lazy 123 l

来自_val的Lazy.Lazy_文件声明此函数用于特殊情况:

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).
他们在谈论哪些案例

如果我从如下值创建一对挂起的计算:

let l1 = lazy 123
let l2 = Lazy.lazy_from_val 123

这两者有什么区别?因为
Lazy.Lazy_是_vall1
Lazy.Lazy_是_vall2
都返回true,表示该值已被强制

lazy\u from\u val
是一个函数,而不是语法。因此,

# 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
#让id=fun x->x;;
val id:'a->'a=
#Lazy.Lazy是(Lazy(id 123));;
-:bool=false
#Lazy.Lazy_是(Lazy.Lazy_from_val(id 123));;
-:bool=true

特殊用途是,如果您需要一个惰性值,但有时您已经计算了一个(非惰性)值。您可以使用
lazy\u from_val
将已计算的值转换为(强制)懒惰版本的值

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\u from\u val
使其工作

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

# 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
# 
#让p()=打印字符串“here\n”;3.
val p:单位->整数=
#设l1=lazy(p());;
val l1:int lazy\u t=
#设l2=Lazy.Lazy_from_val(p());;
在这里
val l2:int Lazy.t=Lazy 3
#f l1;;
在这里
-:int=45
#f l2;;
-:int=45
# 

您可以直接使用显式闭包和引用实现延迟操作。正如Matthias Benkard所指出的,OCaml的惰性机制使用特殊的语法,以使其不那么麻烦。也就是说,
lazy
是一个OCaml关键字,而不是一个函数。

“OCaml的lazy机制使用特殊语法”。。。和特殊的GC功能,以消除间接,已成为无用的,以强制值。真的很好知道,谢谢!(这有好的裁判吗?)