2016-10-02 64 views
-2
(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

回答

0

當你運行該代碼,你會看到((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