Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
clojure:在cond中使用绑定将recur仅放置在尾部位置?_Clojure_Functional Programming - Fatal编程技术网

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

clojure:在cond中使用绑定将recur仅放置在尾部位置?,clojure,functional-programming,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))) :

我有一些代码目前给了我一个错误,因为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))))
(defmethod转发器
长[标度]
(回路[新刻度计数度数]
(续)
(零?计数)新刻度
(
我认为解决这个问题的一种方法是条件绑定,如果我可以说: 当计数小于零时,将计数运算符设置为“inc”,否则设置为“dec”,然后在末尾重复出现

这样就可以解决我的问题了。但我不确定在clojure中如何做到这一点,或者是否可能,什么时候让我们做,什么时候不让我们做。将代码修复为只使用一次重现的最佳方法是什么

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

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

2) 把括号弄错给了我一个令人困惑的错误,这让我感到奇怪的是,两个cond语句都不会被认为是在尾部,因为它们是相互排斥的。我应该多注意一下我的paren完成检查


3) 如果我真的想做条件绑定,我可以使用一个标准的“let”语句,只在其中包含条件逻辑。来自java背景的我有时会忘记clojure在这方面允许的灵活性。

在您最初的问题中,您问“我认为解决这一问题的一种方法是条件绑定,如果我可以说:当count小于零时,将count操作符设置为“inc”,否则设置为“dec”,然后在末尾重复出现。”没有人回答这一部分:

(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)))))
(let [d (if (neg? degree) inc dec)]
  (recur (step scale) (d degree)))
除了您希望在一种情况下调用reverse,而不是在另一种情况下调用reverse,因此您也需要一个条件绑定。下面是一个使用分解结构的绑定示例:

(let [[s d] (if (neg? degree) [reverse inc] [identity dec])]
  (recur (step (s scale)) (d degree)))

尽管正如Andrew Cooke所指出的,在每个“尾”(没有循环)中重复出现的简单cond可以很好地工作。

我不理解您的代码
recur
循环中调用循环,但您的参数列表不匹配。还有,
do
的作用是什么?你在倒数第二行还有一个额外的参数,应该在最后一行。抱歉,“do”是我在做一些调试时留下的,我已经删除了它。嗯,我不认为我的重复参数是错误的,应该有两个值,新的比例和计数。“规模”和“程度”是它们的初始值。我的两个recur语句都传递两个参数。我错过什么了吗?哦,对不起,你说得对。我自己不怎么用。更新了。但是那样的话,为什么循环?!?!我在循环,因为我还在改变它们的值。谢谢你的帕伦捕获,这确实是我的问题!我正在使用vim和rainbow parens,但不知怎的错过了这个。非常感谢。啊,我明白你的意思了。我可以删除loop语句,它将在函数上恢复为REPECTION,这在这种情况下可以正常工作。酷,我会这么做的!谢谢,肖恩。看看你的例子,很明显我可以在let中包含if,但我没有想到要这么做。谢谢
(let [[s d] (if (neg? degree) [reverse inc] [identity dec])]
  (recur (step (s scale)) (d degree)))