【问题标题】:Scheme Error "application: not a procedure"方案错误“应用程序:不是程序”
【发布时间】:2018-05-04 03:13:06
【问题描述】:

我正在阅读 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 个数字是前三个质数,但我不明白错误消息的含义。

【问题讨论】:

标签: function scheme function-call application-error


【解决方案1】:

错误消息表明您正在使用 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 的正确选择......但遗憾的是缺少一些有用的错误消息。

具体来说,在您使用的语言中,if 可能会缺少 else 分支,如果测试失败,它会默默地计算出特殊的 # 值。

哦!可是等等!你还有一个问题……你写

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

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

您可能正在这里寻找begin,如下所示:

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

【讨论】:

  • 谢谢!实际上我正在使用scheme并且在代码之前有一个#lang sicp,但不知何故stackoverflow不能很好地解析它所以我删除了它但忘了提及它。有没有办法增加 DrRacket 中错误消息的输出?我也不明白为什么我需要一个 else 来表示 Scheme 中的 if。顺便说一句,我刚刚添加了一个 else,它抱怨 else 不允许作为表达式。
  • BTW 如果您可以分享有关 Scheme 中条件结构的链接,将不胜感激。我自学了 C++ 和条件和循环只需要大约一个小时来学习,但对于 Scheme 则不然。 SICP 没有提供太多细节,Racket doc 也没有提供太多细节。我已经写了一个多星期的方案,但我仍然不明白。而且 AFAIK 方案没有循环......
  • 这里最好的参考资料是 How to Design Programs,这是一本(免费在线)教科书 (htdp.org),由 DrRacket 的许多作者编写。事实上,Scheme 确实 有循环,以及您在其他编程语言中发现的大多数命令式特性,但 Scheme 通常会组织您以引导您使用函数式解决方案。一个很好的例子与你之前的问题有关:为什么你必须有一个 else?答案来自数学:如果你没有 else,那么函数应该返回什么?而不是考虑做什么...
  • 你想他们返回
  • @NicholasHumphrey 要获得更快节奏的文本,请查看 ds26gte.github.io/tyschemescheme.com/tspl4
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多