ocaml - 如何在Ocaml中实现俄罗斯娃娃模式?

标签 ocaml

在 Javascript 中有一种称为俄罗斯娃娃模式的模式(这也可以称为“一次性”)。基本上,它是一个在某些时候用另一个函数替换自己的函数。

简单的例子:

var func = function(){ 
  func = function(){ console.log("subsequent calls call this...");};
  console.log("first call");
}

因此,您第一次调用 func 时,它将输出“第一次调用”,而下一次(以及随后的时间)将输出“后续调用调用此...”。 (例如,这在 Scheme 中也很容易做到)

我一直在想如何在 Ocaml 中做到这一点?

编辑:我想出的一个解决方案:
 let rec func = ref( fun () -> func := ( fun () -> Printf.printf("subsequent..\n"));Printf.printf("First..\n"));;

称为:
!func () ;;

有趣的是,如果我不在定义中包含“rec”,它就永远不会调用后续函数......它总是打印“First...”。

最佳答案

yzzlr 的回答很好,但有两点说明:

它强制函数的输入为 unit 类型。您可以使用多态版本:

let doll f1 f2 =
  let rec f = ref (fun x -> f := f2; f1 x) in
  (fun x -> !f x);;

你可以不用毛茸茸的递归:
let doll f1 f2 =
  let f = ref f1 in
  f := (fun x -> f := f2; f1 x);
  (fun x -> !f x);;

(用变异代替递归是一个常见的技巧;它实际上可以用来定义固定点而不使用“rec”)

关于ocaml - 如何在Ocaml中实现俄罗斯娃娃模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5370759/

相关文章:

ocaml - OCaml缺点(::)运算符?

ocaml - 有关于 OCaml Sdl 的文档吗?

emacs - 转到函数定义的简单方法(Emacs,Ocaml)

functional-programming - 像SML/NJ中的 `use mine.sml`一样,如何在OCaml的顶层加载ml文件?

ocaml - 如何使用 ocamlbuild 将 -S 标志传递给 ocamlopt?

generics - 为什么编译器会将两个具有不同名称的等效签名的泛型类型变量识别为不同类型?

ocaml - 沙丘 : build library and access it in another project and hide or make inaccessible private or implementation modules

emacs - 失败 : ocamlfind not found on path, 但未使用 -no-ocamlfind(zsh 终端)

ocaml - 结合参数多态性和多态变体(反引号类型)

json - 如何更改 ppx_yojson_conv 表示变体的方式?