首页 > 解决方案 > 方案错误“应用程序:不是程序”

问题描述

我正在阅读 sicp 并正在编写一个程序来从 1,000 中找到前 3 个素数。我正在使用费马方法的更改版本(但是在这种情况下该算法无关紧要,因为我只需要了解错误消息)。整套代码为:

(define (fz-prime number count)
    (if (< count 4)
        (if (= (fz-fermat-loop number 1) 0)
            (fz-prime (+ number 1) count)
            ((display number) (fz-prime (+ number 1) (+ count 1))))))

(define (fz-fermat-loop number count)
    count
    (if (> count 5)
        1
        (if (= (fz-fermat-test number (fz-random number)) 0)
            0
            (fz-fermat-loop number (+ count 1)))))

(define (fz-fermat-test number count)
    (if (= (modulo count number) (modulo (fz-exp-wrapper count number) number))
        1
        0))

(define (fz-random number)
    (random (- number 2)))

(define (fz-exp-wrapper base power)
    (fz-exp base power 1))

(define (fz-exp base power result)
    (if (<= power 0) result
        (fz-exp base (- power 1) (* result base))))

(fz-prime 1000 1)

现在每次我运行代码时,它都会显示以下错误:

100910131019. . application: not a procedure;
 expected a procedure that can be applied to arguments
  given: #<void>
  arguments...:

前 3 个数字是前三个素数,但我不明白错误消息所说的内容。

标签: functionschemefunction-callapplication-error

解决方案


错误消息表明您正在使用 Racket,而且您选择的语言级别禁用了有用的错误消息,例如当我将您的程序复制到 #lang 球拍语言的缓冲区时得到的错误消息:

if: missing an "else" expression in: (if (< count 4) (if (= (fz-fermat-loop number 1) 0) 
(fz-prime (+ number 1) count) ((display number) (fz-prime (+ number 1) (+ count 1)))))

实际上,我敢打赌,您使用的是 Jens Axel Soegaard 的优秀sicp语言,这完全是通过 sicp 工作的正确选择……但遗憾的是缺少一些有用的错误消息。

具体来说,在您使用的语言中, anif可能会丢失一个else分支,如果测试失败,它会默默地评估特殊的 # 值。

哦!可是等等!你有另一个问题......你写

((display number) (fz-prime (+ number 1) (+ count 1)))

我敢打赌你在想,如果你只用两个表达式,比如(display number)and(fz-prime ...)并用括号括起来,这意味着“先做,然后做第二个”。但实际上,这意味着“第一个表达式计算为一个函数;使用计算剩余表达式的结果调用它”,#void这正是(display ...)返回的结果。

您可能正在寻找begin,在这里,像这样:

(begin 
   (display number) 
   (fz-prime (+ number 1) (+ count 1)))

推荐阅读