clojure 中的递归代码和 class 转换异常

recursive code in clojure and class cast exception

(defn fib [n]
         (if ((= n 0) 0)
           ((= n 1) 1)
           (:else (+ (fib (- n 1)) 
              (fib (- n 2))))))
(fib 10)

ClassCastException java.lang.Boolean 无法转换为 clojure.lang.IFn

与以下相同的异常。

(defn A [x y]
 (cond ((= y 0) 0)
       ((= x 0) (* 2 y))
       ((= y 1) 2)
       (:else (A (- x 1) (A x (- y 1))))))
(A  1 10)

这里有什么问题无法理解,请解释一下?

你们太亲密了!

(defn A [x y]
  (cond (= y 0) 0
        (= x 0) (* 2 y)
        (= y 1) 2
        :else (A (- x 1)
                 (A x (- y 1)))))

您只是在 cond 表格外加了太多括号。

现在工作正常:

user=> (A  1 10)
1024

您的递归 fib 函数中存在一些类似的问题。请特别注意缩进 - 这将始终帮助您找出问题所在。

在这种特殊情况下,异常 ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn 被此行抛出:

((= n 1) 1)

... 因为 (= n 1) 被评估为布尔值 true 或 false,并且由于此结果布尔值位于 ((= n 1) 1) 形式的第一个位置,这意味着 Clojure 将尝试将布尔值作为函数调用 (clojure.lang.IFn).

这就是 Clojure 真正看到的:

(true 1)

这就是 Clojure 试图将布尔值转换为 IFn 的原因。 IFn 是一个 Java 接口,表示可调用函数。

我希望这是有道理的。