【问题标题】:Recursive function references in OCaml?OCaml中的递归函数引用?
【发布时间】:2012-04-30 15:26:26
【问题描述】:

今天我们学习了 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 绑定到另一个函数。任何帮助表示赞赏!

【问题讨论】:

    标签: function reference ocaml sml


    【解决方案1】:

    你的代码在 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)
    

    【讨论】:

    • (在 SML 中使用and 也是惯用的。这只是一个说明打结的例子。)
    • 哇,我觉得我之前尝试过,但遇到了错误,但我一定是错过了什么,非常感谢!
    【解决方案2】:

    等效的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 代码相同。

    (编辑补充:实际上,Thomas 的代码更漂亮一点!)

    【讨论】:

      【解决方案3】:

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

      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。这不是对您的问题的直接回答,而是以一种纯粹的功能方式展示该模式的外观。

      【讨论】:

      • @JeffreyScofield 是的,但你需要-rectypes
      • @gilles:我知道我遗漏了一些东西...稍后我将使用递归类型的常用解决方法之一对其进行编辑...
      猜你喜欢
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 2013-02-23
      • 2018-04-02
      • 2015-12-08
      • 2011-10-16
      相关资源
      最近更新 更多