OCaml中的弱多态性

inn*_*cat 7 ocaml functional-programming ml value-restriction

我对OCaml中的弱多态性有点困惑.

请参阅以下代码片段,我在其中定义一个函数remember:

let remember x =
   let cache = ref None in
      match !cache with
       | Some y -> y
       | None -> cache := Some x; x
;;
Run Code Online (Sandbox Code Playgroud)

编译器可以推断出多态类型'a -> 'a,并cache在本地使用.

但是当我修改上面的代码时

let remember =
   let cache = ref None in
    (fun x ->  match !cache with
         | Some y -> y
         | None -> cache := Some x; x)
;;
Run Code Online (Sandbox Code Playgroud)

编译器推断出弱多态类型'_a -> '_a,似乎cache在调用之间共享remember.

为什么编译器在这里推断出弱多态类型以及为什么要cache共享?

更重要的是,如果我再次更改代码

let remember x =
   let cache = ref None in
    (fun z ->  match !cache with
         | Some y -> z
         | None -> cache := Some x; x)
;;
Run Code Online (Sandbox Code Playgroud)

编译器推断出多态类型'a -> 'a -> 'acache变为本地使用.为什么会这样?

Dan*_*zer 8

let remember =
 let cache = ref None in
  (fun x ->  match !cache with
       | Some y -> y
       | None -> cache := Some x; x)
;;
Run Code Online (Sandbox Code Playgroud)

这里cache由返回的函数关闭.但在我们宣布的时候cache,我们没有关于这种类型的信息; 它将由任何类型确定,xcacheremember定义时创建.

但由于这是一个闭包,我们可以这样做:

> remember 1
  1
Run Code Online (Sandbox Code Playgroud)

现在很明显,cache : int option ref因为我们实际上存储了一些东西.由于只有一个cache,remember只能存储一种类型.

在下一个,你关闭了2件事,x并且cache.由于我们创建了一个新的cacheref,每次调用remember该类型都可以再次完全多态.类型不是弱多态的原因是因为我们知道我们将存储x它并且xcache创建时我们有类型.


t0y*_*yv0 6

这似乎与价值限制有关.完全限制(如在SML中)将完全拒绝您的代码.Jacques Garrigue撰写的"放宽价值限制"一文中描述了弱多态类型,我在阅读你的问题后无可辩驳地说:

http://caml.inria.fr/pub/papers/garrigue-value_restriction-fiwflp04.pdf

cache如果你有一个ML代码意味着正确的心智模型,那么在调用中共享的事实应该是显而易见的.您正在定义两个值,remembercache.嵌套只是使cache块的私有范围.