clojure:在 cond 中使用绑定(bind)仅将 recur 放置在尾部位置?

标签 clojure functional-programming

我有一些代码当前给我一个错误,因为 recur 只能位于尾部位置。这是函数:

(defmethod transposer
    Long [scale degree]
    (loop [new-scale scale count degree]
    (cond 
        (zero? count) new-scale 
        (< count 0) (recur (step (reverse new-scale)) (inc count)))
        :else (recur (step new-scale) (dec count))))

我认为解决这个问题的一种方法是条件绑定(bind),如果我可以说: 当count小于零时,将count-operator设置为“inc”,否则设置为“dec”,然后在最后重复。

那么这将解决我的问题。但我不确定如何在 clojure 中执行此操作,或者如果可能的话,when-let 和 if-let 似乎不会执行此操作。将我的代码修复为仅使用一次重复的最佳方法是什么?

编辑:我在这里学到了一些东西:

1) 如果没有循环语句,“recur”将递归回到 defn。在我读的书中,所有recur的例子都使用loop/recur,所以我认为有一个循环是有必要的。事实并非如此,我的循环语句是多余的。

2) 括号错误给了我一个令人困惑的错误,令我感到奇怪的是,两个 cond 语句都不会被视为位于尾部,因为它们是互斥的。我应该更加注意我的 paren 完成检查器。

3) 如果我确实想要进行条件绑定(bind),我可以使用标准的“let”语句并仅在其中包含条件逻辑。由于我有 Java 背景,我有时会忘记 clojure 在这方面所提供的灵 active 。

最佳答案

(defn foo [scale degree]
  (loop [new-scale scale count degree]
    (cond 
      (zero? count) new-scale 
      (< count 0) (recur (step (reverse new-scale)) (inc count))
      :else (recur (step new-scale) (dec count)))))

我认为更接近你想要的(它不会给出尾部错误;我只是使用 defn 来测试独立)。

多次recur没有问题 - 尾递归并不意味着它必须在文本的最后一行,只是在返回时不再进行计算。

主要问题是括号困惑(count之后太多)。我建议使用一个自动缩进的编辑器(并过度使用自动缩进)。这会立即显示parens问题(我在intellij idea中使用la clojure插件,但我确信其他人也有类似的功能)。

更新:为什么需要循环

(defn foo [scale degree]
  (cond 
    (zero? degree) scale 
    (< degree 0) (recur (step (reverse scale)) (inc degree))
    :else (recur (step scale) (dec degree))))

关于clojure:在 cond 中使用绑定(bind)仅将 recur 放置在尾部位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10508591/

相关文章:

用于 SPNEGO/Kerberos-http 身份验证的 clojure 库

python - Python 中更好的函数组合

haskell - 解析模式:? [closed]中的错误

clojure - #'namespace/name_of_function中的错误

generics - 是否有语言在作为参数传递的函数上实现保留泛型?

十分钟 Javascript : What is going on in this example code illustrating lazy scoping?

python - 使用 reduce() 的有用代码?

html - 我在哪里可以找到 compojure.html?

clojure 将lazy-seq转换为 HashMap

clojure - VimClojure 安装教程