如何找到“不是程序”错误

问题描述:

(define (comp f g) 
    (lambda (x)(f (g x)))) 

(define (complement f) (cond ((equal? (comp f (lambda (g) g)) #t) #f) 
          ((equal? (comp f (lambda (g) g)) #f) #t))) 

((complement odd?)2) 

它一直说((补数奇?)2)不是一个过程。我不知道如何解决它。如何找到“不是程序”错误

+0

你的'complement'实现是一团糟。它真的只需要在论点上写下“不”。补充需要返回一个程序。我看到'cond'返回'#f','#t'和未定义的值,当缺少'else'子句时,这些都不是过程,因此当您尝试应用时会引发一个“不是过程”结果。 – Sylwester

+0

我该如何解决它? – siri

+0

通过使用'comp'将'complement'从'cond'改为'cond'。 '(odd?x)'的补码是'(not(odd?x))',因此'((comp not odd?)x)'。 – Sylwester

当你运行该代码,你会看到((complement odd?) 2)是在定义红色,你会得到以下错误:

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

因此,这将意味着(complement odd?)不返回一个程序,但价值#<void>。让我们试着说:

(complement odd?) 
; ==> nothing (aka #<void>) 

如果你真的想看到它的地方使用它:

(list (complement odd?)) 
; ==> (#<void>) now you see it 

这意味着你没有处理在cond所有可能的检查,在complement,我看到为什么..你有没有试过comp

(comp f (lambda (g) g)) ; ==> #<procedure> 

确实足够使用comp成为一个过程。这并不奇怪,因为body有一个lambda表单,表示返回将是一个过程。 它永远不会是#t#f如果没有else(缺省)术语,表示没有任何谓词变为true cond将返回特定于实现的缺省值。在Racket中,这是#<void>,它受REPL支持,但在其他实现中,它可以是banana或实施者希望它的任何内容,因此您应始终拥有else子句。如果你不认为你需要它,然后做(else (error "should never happen")),你很好去。 (试一试)

cond的后果是#t#f。这意味着,如果你的代码前人的精力都工作你会得到,而不是此错误消息:

application: not a procedure; 
expected a procedure that can be applied to arguments 
    given: #t 

每个地方你的回报smething,是不是因为你正在使用的结果作为一个过程,这将是一个错误的程序。你需要改变你的实现,以便它总是返回一个过程。

所以,这是如何找到“不是程序”错误的答案。这不是如何解决你的程序的答案,但是因为这是世界上最简单的程序,所以我会添加它。你有一个程序comp需要两个程序,并返回两个组成。例如。如果你想add2你可以(define add2 (comp add1 add1))complement必须是假值#f变为#t而所有的真值都变为#fnot做到这一点所以notodd?组成将成为工作的程序一样even?

(define (complement f) 
    (comp not f)) ; comp returns a procedure always 

(define my-even? (complement odd?)) 
(my-even? 2) ; ==> #t 

由于我们没有发生变异任何你可以使用替换法检查什么这样做:

(my-even? 2)      ; ==> 
((comp not odd?) 2)    ; ==> 
(((lambda (x) (not (odd? x))) 2) ; ==> 
(not (odd? 2))     ; ==> 
(not #f)       ; ==> 
#t