2014-03-04 44 views
1

我寫了一個相對簡單的銀行帳戶函數,但是當我嘗試運行它時,出現TypeError,我不確定爲什麼?這是SICP的直接,所以解決方案很容易獲得,我只想了解爲什麼我的答案會產生這種錯誤。有什麼想法嗎?這裏是我的代碼:TypeError,該對象不適用

(define (make-password-account balance password) 
    (define (withdraw amount) 
     (if (>= balance amount) 
      (begin (set! balance (- balance amount)) 
       balance) 
      "Insufficient Funds")) 
    (define (deposit amount) 
     (set! balance (+ balance amount)) 
     balance) 
    (define (dispatch users-guess-at-password m) 
      (if (eq? users-guess-at-password password) 
       (cond ((eq? m 'withdraw) withdraw) 
         ((eq? m 'deposit) deposit) 
         (else (error "Unknown Request --make-account" m))) 
       "INVALID PASSWORD")) 
dispatch) 

下面是從解釋相關的解釋輸入和輸出:

..loaded function... 
>(define acc (make-password-account 100 'secret)) 
acc 
>((acc 's 'withdraw) 2) 
;Stack Trace: 
0 TypeError: The object "Invalid Password" is not applicable. 
1 ((acc (quote s) (quote withdraw) 2) 

回答

3

目前你的代碼是這樣做的:

((acc 's 'withdraw) 2) 
((dispatch 's 'withdraw) 2) 
("INVALID PASSWORD" 2) 
=> TypeError: The object "INVALID PASSWORD" is not applicable. 

你必須處理的情況下,其中的密碼進入是錯誤的。因爲如果密碼不正確,你不能做任何有用的東西與該帳戶,您應該發出錯誤信號,停止執行情況,比如替換這一行:

"INVALID PASSWORD" 

有了這個:

(error "INVALID PASSWORD") 

現在該過程將返回一個有意義的錯誤消息並停止執行。或者,如果發出錯誤信號過於劇烈,您可以按照@molbdnilo的建議返回一個字符串。一旦再次更換爲"INVALID PASSWORD"建議的程序,這不管它接收的參數會返回錯誤字符串:

(lambda (x) "INVALID PASSWORD") 

現在執行將是這樣的:

((acc 's 'withdraw) 2) 
((dispatch 's 'withdraw) 2) 
((lambda (x) "INVALID PASSWORD") 2) 
=> "INVALID PASSWORD" 
1

既然你傳遞了錯誤的密碼,

(acc 's 'withdraw) 

也就是說,

(dispatch 's 'withdraw) 

評價s到

"INVALID PASSWORD" 

並且您正試圖將其應用於數字2,但您不能,因爲它不是函數。

你可以使用一個函數,而不是一個字符串,類似於其他情況:

(lambda (x) "Invalid password") 
相關問題