为什么我在Clojure中尝试使用Simpson规则时会出现强制转换错误?

时间:2011-05-24 00:08:05

标签: clojure lazy-evaluation sicp eager

我正在尝试使用Clojure完成SICP中的一些练习,但是我现在执行Simpson规则的方法出错(例如1-29)。这与懒惰/急切的评估有关吗?有想法该怎么解决这个吗?错误和代码如下:

java.lang.ClassCastException:user $ simpson $ h__1445无法强制转换为java.lang.Number  在clojure.lang.Numbers.divide(Numbers.java:139)

以下是代码:

(defn simpson [f a b n]
  (defn h [] (/ (- b a) n))
  (defn simpson-term [k]
    (defn y [] (f (+ a (* k h))))
    (cond 
      (= k 0) y
      (= k n) y
      (even? k) (* 2 y)
      :else (* 4 y)))
  (* (/ h 3)
     (sum simpson-term 0 inc n)))

1 个答案:

答案 0 :(得分:7)

您将h定义为无参数的函数,然后尝试使用它,就像它是一个数字一样。我也不确定你用(sum simpson-term 0 inc n)得到了什么;我只是假设sum是你从SICP获得的一些魔法,并且你传递给它的论据是正确的(我隐约回想起它们定义了某种通用的总和)。

另一方面,在def内嵌套defndefn几乎总是一个糟糕的主意。您可能需要let(对于临时或本地的)或其他顶级defn

请记住,我多年没有编写simpson函数,并且没有检查过这个算法的正确性 ,这里的草图更接近于比你的“正确的形状”:

(defn simpson [f a b n]
  (let [h (/ (- b a) n)
        simpson-term (fn [k]
                       (let [y (f (+ a (* k h)))]
                         (cond 
                          (= k 0) y
                          (= k n) y
                          (even? k) (* 2 y)
                          :else (* 4 y))))]
    (* (/ h 3)
       (sum simpson-term 0 inc n))))