clojure:在cond中使用绑定将recur仅放置在尾部位置?
我有一些代码目前给了我一个错误,因为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))) :
(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)))