You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DrRacket/Scheme求二次方程根程序报错:not a procedure

问题分析与修正

你遇到的错误核心是多余的括号导致的过程调用错误,咱们一步步拆解:

错误根源

看你写的roots函数:

(define roots (lambda (a b c) ((if (> (D a b c) 0) (cons (/ (+ (- b) (sqrt (D a b c))) (* 2 a)) (/ (- (- b) (sqrt (D a b c))) (* 2 a))) #f)))

注意最外层的((if ...))——在Scheme里,任何被括号包裹的表达式都会被当作过程调用处理。这里if表达式的结果是(cons ... ...)生成的点对(比如(-1 . -2)),但外层的括号试图把这个点对当作可调用的过程来执行,而点对并不是过程,所以就报了application: not a procedure的错误。

修正后的代码

只需要把外层多余的括号去掉,让if直接返回对应的结果即可:

(define na2 (lambda (x) (* x x)))
(define D (lambda (a b c) (- (na2 b) (* 4 a c))))
(define roots (lambda (a b c) 
                (if (> (D a b c) 0)
                    (cons (/ (+ (- b) (sqrt (D a b c))) (* 2 a))
                          (/ (- (- b) (sqrt (D a b c))) (* 2 a)))
                    #f)))

现在执行(roots 1 3 2)就会正确返回(-1 . -2),不会报错了。

额外优化建议

你的代码里重复计算了三次(D a b c)和两次sqrt,可以把判别式的结果先存起来,既提高效率又让代码更清晰:

(define na2 (lambda (x) (* x x)))
(define D (lambda (a b c) (- (na2 b) (* 4 a c))))
(define roots (lambda (a b c) 
                (let ((discriminant (D a b c)))
                  (if (> discriminant 0)
                      (let ((sqrt-d (sqrt discriminant)))
                        (cons (/ (+ (- b) sqrt-d) (* 2 a))
                              (/ (- (- b) sqrt-d) (* 2 a))))
                      #f))))

这样只计算一次判别式和一次平方根,代码可读性也更好。

内容的提问来源于stack exchange,提问作者SheldonCopper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:53:45