OCaml中的递归函数引用?

时间:2012-04-19 06:13:45

标签: function reference ocaml sml

今天我们在SML中学到了“打结”,你有类似的东西

val tempFunc = ref (fn k:int => true);
fun even x = if x = 0 then true else !tempFunc(x-1);
fun odd x = if x = 0 then false else even(x-1);
tempFunc := odd;

我正在使用类似的ocaml,但我只是在做同样的事情。我发现最接近的是

let tempFunc {contents =x}=x;;

但我真的不明白,以及如何将tempFunc绑定到另一个函数。任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:9)

您在OCaml中直接翻译代码是:

let tempFunc = ref (fun k -> true)
let even x = if x = 0 then true else !tempFunc (x-1)
let odd x = if x = 0 then false else even (x-1)
let () = tempFunc := odd

执行此操作的惯用方法(就像在SML中一样)是使用递归函数:

let rec even x = if x = 0 then true  else odd  (x-1)
and     odd  x = if x = 0 then false else even (x-1)

答案 1 :(得分:4)

等效的OCaml代码是

let tempFunc = ref (fun (k: int) -> true);;

let even x = if x = 0 then true else !tempFunc (x-1);;

let odd x = if x = 0 then false else even (x-1);;

tempFunc := odd;;

正如您所说,它与SML代码几乎完全相同。

(编辑补充说:实际上,托马斯的代码有点漂亮!)

答案 2 :(得分:1)

还有另一种方法可以在不使用引用的情况下使用相同的东西:

let rec even_helper f x = if x = 0 then true else f even_helper (x-1);;
let rec odd_helper f x = if x = 0 then false else f odd_helper (x-1);;
let even = even_helper odd_helper;;
let odd = odd_helper even_helper;;

请注意,此代码涉及无人看守的递归类型:帮助程序的类型为('a -> int -> bool) -> int -> bool as 'a,这意味着帮助程序的第一个参数是一个函数,其第一个参数是帮助程序。 Ocaml接受此类型,但仅当您将-rectypes选项传递给编译器时才会接受。

使用更多功能,您可以完全取消rec。这不是你问题的直接答案,而是一个侧面轨道,展示了这种模式在纯粹功能方面的外观。