3

作为对 SO 问题的回答,我正在构建一个循环函数,并构建了我迄今为止最复杂的解构,它奇迹般地起作用:

(defn fib?
  [a b & [c & r]]
  (if (= c (+ a b))
    (if r
      (recur b c r)
      true)
    false))

(fib? 0 1 1)
=> true

(fib? 2 3 5 8 13)
=> true

但我不知道为什么它应该工作。中r使用的recur是一个集合,这会使原始函数失败。

(fib? 2 3 [5 8 13])
=> false

我想在apply recur那里使用类似的东西,但由于recur是一种特殊形式,这是不可能的。所以我尝试不使用它并且它有效。是否recur具有神奇的自动应用属性,或者还有其他我没有看到的东西。

4

1 回答 1

3

答案分为两部分:

  1. 可变参数函数的“rest”参数成为递归recur到函数顶部的任何形式的最终参数。在这一点上,它不再是特别的。您通常希望确保在该位置传递的任何值实际上都是连续的,但即使这样也不是强制的。1

  2. 解构只是fnandlet宏提供的语法糖。在其参数向量中使用解构的形式的脱糖版本fn采用一定数量的常规参数,然后let以包裹整个主体的形式将它们解构。因此,如果您递归到在其参数向量中使用解构的函数的顶部,则新值将在下一次迭代中被解构。


1例如,((fn [& xs] (if (seq? xs) (recur (first xs)) xs)) 1 2 3)返回1.

于 2014-03-30T23:28:41.720 回答