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

发布于 2024-11-09 07:27:45 字数 525 浏览 6 评论 0原文

我正在尝试使用 Clojure 完成 SICP 中的一些练习,但我当前执行辛普森规则的方法(例如 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)))

I'm trying to work through some of the exercises in SICP using Clojure, but am getting an error with my current method of executing Simpson's rule (ex. 1-29). Does this have to do with lazy/eager evalution? Any ideas on how to fix this? Error and code are below:

java.lang.ClassCastException: user$simpson$h__1445 cannot be cast to java.lang.Number
at clojure.lang.Numbers.divide (Numbers.java:139)

Here is the code:

(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)))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落叶缤纷 2024-11-16 07:27:45

您将 h 定义为无参数的函数,然后尝试将它当作数字来使用。我也不确定您对 (sum simpson-term 0 inc n); 有何看法;我只是假设 sum 是您从 SICP 获得的某种魔法,并且您传递给它的参数是正确的(我隐约记得它们定义了某种通用总和)。

另一件事是,将 defdefn 嵌套在 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))))

You define h as a function of no arguments, and then try to use it as though it were a number. I'm also not sure what you're getting at with (sum simpson-term 0 inc n); I'll just assume that sum is some magic you got from SICP and that the arguments you're passing to it are right (I vaguely recall them defining a generic sum of some kind).

The other thing is, it's almost always a terrible idea to have a def or defn nested within a defn. You probably want either let (for something temporary or local) or another top-level defn.

Bearing in mind that I haven't written a simpson function for years, and haven't inspected this one for algorithmic correctness at all, here's a sketch that is closer to the "right shape" than yours:

(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))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文