这个OCaml代码如何工作?

时间:2015-03-13 16:02:39

标签: ocaml

以下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 ()的调用会创建一个2元组的函数。元组中的第一个函数在封闭的ref单元格中存储任意值;第二个函数检索它。如果第二个函数给出了类型为t的错误值,则返回None。但是,在我看来,这将导致ref单元被清除,因此进一步尝试检索值失败,这不会发生。另外,我一般不了解将错误值传递给投影函数get时会发生什么。

1 个答案:

答案 0 :(得分:7)

调用embed后,系统会为rput分配新的参考get和两个新的闭包。当一些put被调用时,它返回一个新函数(让我们称之为setter),它的闭包中也有r

  • 如果该setter被赋予相应的get,则两个闭包中捕获的r都是相同的,因此当get调用f true时,它会修改r关闭getlet 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指定给非对应的get,则r捕获的get与设置者不同。 (我们称之为r1r2

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

    由于get需要始终清除r,因此我们知道在调用之前 getr2None。因此get将返回None