为什么这段代码错了?如何重演?#39;工作?

时间:2014-03-11 14:11:49

标签: clojure

我不知道为什么下面的代码是错误的:

(defn factorial [n]
  (loop [n n
         acc 1]
    (if (zero? n)
      acc
      (recur (* acc n)(dec n)))))

 (= 1 (factorial 1))

recur如何运作?

1 个答案:

答案 0 :(得分:3)

recur的参数是错误的。

  • n应该成为(dec n)
  • acc应该成为(* acc n)

所以它应该是

(recur (dec n) (* acc n))

我们可以重新制作给定的算法,看看里面发生了什么。

如果我们将这对参数表示为向量,则生成下一对的函数是

(fn [[n acc]] [(* acc n) (dec n)])

我们可以通过将no应用于上面的函数,从iterate开始,为给定的[no 1]生成无限的可能对。

(fn [no]
  (iterate (fn [[n acc]] [(* acc n) (dec n)]) [no 1]))

将此应用于1生成

([1 1] [1 0] [0 0] [0 -1] ...)

我们停在第2个元素,第一个是初始0,返回另一个0

如果我们以正确的方式放置参数,我们可以得到正确的factorial

(defn factorial [no]
  ((comp second first)
         (drop-while
           (comp not zero? first)
           (iterate (fn [[n acc]] [(dec n) (* acc n)]) [no 1]))))

这将返回序列中second对的first元素,其中零first(Duh!)。

绝对过于复杂以供正常使用,但它有效吗?

=> (map factorial (range 6))
(1 1 2 6 24 120)

是。