【问题标题】:How to achieve mutual recursion to avoid names not being defined?如何实现相互递归以避免名称未定义?
【发布时间】:2018-11-06 07:46:29
【问题描述】:

我有一个 clojure 程序,其中两个函数递归地互相调用:

(defn f1
...
(f2 ...)
)


(defn f2
...
(f1 ...)
)

编译器在f1 中给出错误。意思是 f2 没有定义。有没有办法declareclojure 中的一个函数。我可以验证递归是否真的终止了。

【问题讨论】:

标签: clojure functional-programming mutual-recursion


【解决方案1】:

字面意思是declare

(declare f2)
(defn f1 []
  (f2))

(defn f2 []
  (f1))

【讨论】:

    【解决方案2】:

    还有一个letfn 形式用于(可能)相互递归的函数:

    user=> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
                   (f2 [x] (f1 (inc x)))]
             (f2 0))
    
    ;;=> 10
    

    更新 如果您在全局范围内需要这些功能,您始终可以在letfn 中使用def。至于我,我发现这种方法比declare 更干净一点(尤其是对于相互递归的方法):

    user> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
                  (f2 [x] (f1 (inc x)))]
            (def f1 f1)
            (def f2 f2))
    #'user/f2
    
    user> (f2 0)
    ;;=> 10
    

    【讨论】:

    • 有趣。我不知道letfn 允许这样做。当然,这只有在本地定义函数就足够的情况下才有效。
    • @Carcigenicate,你总是可以在letfn 中使用def。我有时这样做是为了强调这些功能是相互关联的。更新了我的答案。
    猜你喜欢
    • 2014-01-14
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多