2

Clojure を使用して SICP のいくつかの演習を実行しようとしていますが、Simpson のルールを実行する現在の方法 (例 1-29) でエラーが発生します。これは遅延/熱心な評価と関係がありますか? これを修正する方法についてのアイデアはありますか? エラーとコードは次のとおりです。

java.lang.ClassCastException: user$simpson$h__1445 は clojure.lang.Numbers.divide で java.lang.Number にキャストできません (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)))
4

1 に答える 1

7

引数のない関数として定義hし、それを数値であるかのように使用しようとします。また、あなたが何をしているのかわかりません(sum simpson-term 0 inc n)。それはあなたがSICPから得た魔法であり、それに渡した引数が正しいと仮定しますsum(ある種の一般的な合計を定義していたことをぼんやりと思い出します)。

defもう 1 つのことは、 ordefnを 内にネストすることは、ほとんどの場合、ひどい考えdefnです。おそらく、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))))
于 2011-05-24T00:30:20.307 に答える