我如何展平传递给recur的参数?

我正在尝试了解loop/recur. 我想将函数的返回向量传递回循环,我尝试过这样的事情:

(defn foo [x y] 
  [(dec x) y])

(loop [x 3 y 4]
  (if (> x 0)
    (do
      (prn x y)
      (recur (foo x y)))))

这给出了:

1. Caused by java.lang.IllegalArgumentException
   Mismatched argument count to recur, expected: 2 args, got: 1

现在我可以将循环参数更改为另一种有效的形式:

(defn foo [x y] 
  [(dec x) y])

(loop [[x y] [3 4]]
  (if (> x 0)
    (do
      (prn x y)
      (recur (foo x y)))))

我想知道是否有任何方法可以更改第一个代码以离开(loop [x 3 y 4] ...)但更改以recur某种方式传递给的参数。我想我需要类似apply函数的东西,但我无法使用它recur,因为recur它不是函数。

回答

没有简单的方法可以解决。 recur是一种特殊的形式,Clojures 绕过 JVM 的方式不容易获得 TCO。

因此,您不能apply在此处使用(这将是使用列表中的参数调用函数的解决方案)。

所以你必须坚持结果,foo然后recur与那些。注意旁边:if只有一个分支是 just when

(defn foo [x y] 
  [(dec x) y])

(loop [x 3 y 4]
  (when (> x 0)
    (prn x y)
    (let [[x' y'] (foo x y)] 
      (recur x' y'))))

如果你的领域真的是[x y](例如坐标),我的建议是围绕它构建你的函数,不要在有时使用向量和有时传递 x/y 之间跳转。


以上是我如何展平传递给recur的参数?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>