2016-10-02 2 views
-2

Es bleibt zu sagen, dass ((Komplement ungerade?) 2) ist keine Prozedur. Ich bin mir nicht sicher, wie ich das beheben soll.So finden Sie "nicht eine Prozedur" Fehler

+0

Ihre Implementierung von 'Komplement' ist ein Durcheinander. Es muss nur "nicht" mit dem Argument komponiert werden. Komplement muss eine Prozedur zurückgeben.Ich sehe das 'cond', das' # f', '# t' und den undefinierten Wert für die fehlende' else'-Klausel zurückgibt, und keines davon ist eine Prozedur und provoziert daher eine "ist keine Prozedur", wenn Sie versuchen, sich zu bewerben das Ergebnis. – Sylwester

+0

Wie könnte ich das beheben? – siri

+0

Indem Sie 'complement' von einem' cond' ändern, indem Sie einfach 'comp' verwenden. Das Komplement von '(odd? X)' ist '(nicht (odd? X))' und somit '((comp not odd?) X)'. – Sylwester

Antwort

0

Wenn Sie diesen Code ausführen Sie werden sehen, dass ((complement odd?) 2) in den Definitionen rot ist und Sie die folgende Fehlermeldung erhalten:

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

das würde also bedeuten (complement odd?) kein Verfahren zurück, sondern den Wert #<void>. Versuchen wir, dass:

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

Wenn Sie wirklich sehen wollen, es es irgendwo verwenden:

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

Das heißt, Sie nicht alle möglichen Kontrollen im cond in complement und ich sehe, warum Handhabung .. Haben Sie versucht comp?

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

Sicher genug, um die Verwendung von comp wird ein Verfahren. Nicht seltsam, da der Körper eine Lambda-Form hat, die angibt, dass die Rückkehr eine Prozedur wäre. Es wird nie #t oder #f Wenn Sie keinen else (Standard) Begriff für, wenn keine Ihrer Prädikate wurde erfüllt cond gibt eine Implementierung spezifische defauls Wert. In Racket ist dies #<void>, die durch die REPL unterdrückt wird, aber in anderen Implementierungen kann es banana oder was auch immer die Implementierer wollen, so dass Sie immer eine else Klausel haben sollten. Wenn Sie nicht denken, dass Sie es brauchen, dann tun Sie (else (error "should never happen")) und Sie sind gut zu gehen. (versuchen Sie es)

Die Folgen in Ihrem cond sind #t und #f. Das bedeutet, dass, wenn Ihr Code gearbeitet hat sould Sie diese Fehlermeldung stattdessen bekommen haben würden:

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

Für jeden Ort, um Ihre Rückkehr smething das kein Verfahren ist, dass ein Fehler wäre, da Sie das Ergebnis als ein Verfahren verwenden . Sie müssen Ihre Implementierung so ändern, dass sie immer eine Prozedur zurückgibt.

Also, das ist die Antwort, wie man "nicht eine Prozedur" Fehler findet. Es ist nicht die Antwort darauf, wie man die Prozedur repariert, aber da dies das einfachste Verfahren der Welt ist, füge ich es hinzu. Sie haben eine Prozedur comp, die zwei Prozeduren verwendet und die Zusammensetzung der beiden zurückgibt. z.B. Wenn Sie add2 möchten, können Sie (define add2 (comp add1 add1)). Die complement muss sein, dass der falsche Wert #f#t wird, während alle wahren Werte #f werden. not tut dies, so dass die Zusammensetzung von not und odd? würde das Verfahren geworden, die die gleiche wie even? funktioniert:

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

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

Da wir Sie Substitutionsmethode nicht mutieren alles verwenden können, um zu überprüfen, was das bedeutet:

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