以下OCaml代码创建了一个通用类型(不是我的,来自Jane Street的网站):
module Univ : sig
type t
val embed: unit -> ('a -> t) * (t -> 'a option)
end = struct
type t = bool -> unit
let embed () =
let r = ref None in
let put x =
let sx = Some x in
fun b -> r := if b then sx else None
in
let get f =
f true;
let res = !r in
f false; res
in
put, get
end
Run Code Online (Sandbox Code Playgroud)
创建一个通用类型.在其中,调用embed ()创建一个2元组的函数.元组中的第一个函数在封闭的ref单元格中存储任意值; 第二个函数检索它.如果给第二个函数输入了错误的类型t,则返回None.但是,在我看来,这将导致ref单元被清除,因此进一步尝试检索值失败,这不会发生.另外,我一般不了解将错误值传递给投影函数get时会发生什么.
当embed被调用时,一个新的参考r和功能两个新鲜关闭put和get分配.当一些put被调用时,它返回一个新的函数(让我们称之为setter),它r在闭包中也有.
如果给对应的setter get,则r两个闭包中捕获的是相同的,因此在get调用时f true,它会修改rin get闭包,并let res = !r读取一个Some值.
let get f =
f true; (* assign the shared reference r *)
let res = !r in (* read r *)
f false; (* clear r *)
res
Run Code Online (Sandbox Code Playgroud)如果设置器被赋予非对应的get,则r捕获者get和设置者不一样.(让我们称他们r1和r2)
let get f =
f true; (* assign r1 *)
let res = !r in (* read r2 *)
f false; (* clear r1 *)
res
Run Code Online (Sandbox Code Playgroud)
由于get得到了始终清理r,我们知道在调用之前
get,r2是None.因此get会回来None.