这个 OCaml 代码是如何工作的?

How does this OCaml code work?

以下 OCaml 代码创建了一个通用类型(不是我的,来自 Jane Street's website):

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

创建通用类型。在其中,对 embed () 的调用创建了一个二元组函数。元组中的第一个函数在封闭的引用单元中存储一个任意值;第二个函数检索它。如果将类型 t 的错误值提供给第二个函数,则它 returns None 代替。但是,在我看来,这会导致清除引用单元格,从而进一步尝试检索失败的值,但这并没有发生。另外,我一般不明白将错误的值传递给投影函数 get 时会发生什么。

当调用 embed 时,为函数 putget 分配一个新的引用 r 和两个新的闭包。当某些 put 被调用时,它 return 是一个新函数(我们称它为 setter),它的闭包中也有 r

  • 如果 setter 被赋予相应的 get,那么在两个闭包中捕获的 r 是相同的,因此当 get 调用f true,它修改 get 闭包中的 rlet res = !r 读取一个 Some 值。

    let get f =
      f true;         (* assign the shared reference r *)
      let res = !r in (* read   r *)
      f false;        (* clear  r *)
      res
    
  • 如果setter给了一个不对应的getrget捕获,setter不一样。 (我们称它们为 r1r2

    let get f =
      f true;         (* assign r1 *)
      let res = !r in (* read   r2 *)
      f false;        (* clear  r1 *)
      res
    

    由于 get 总是负责清除 r,我们知道在调用之前 getr2None。因此 get 将 return None