解构:这怎么可能有效?

时间:2014-03-30 23:18:45

标签: clojure destructuring

作为对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是否具有神奇的自动应用属性,或者还有其他我没有看到的内容。

1 个答案:

答案 0 :(得分:3)

答案的两个部分:

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

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


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