2013-12-09 42 views
0

所以我有3個函數定義在計劃中,sumlist列表中加入所有數字,並且意思是給我列表的意思。 mean2調用意味着並做同樣的事情,但我得到一個錯誤。它說錯誤來自sumlist函數。DrRacket /計劃:違反合同,預計數量?

(define (sumlist lst)(if(null? lst)0 (+(car lst)(sumlist(cdr lst))))) 
(define mean (lambda x(/(sumlist x)(length x)))) 
(define mean2 (lambda x(mean x))) 

這是我如何調用函數

(mean 1 2 3 4 5) 
=>3    ;it works 

(mean2 1 2 3 4 5) 
+: contract violation 
expected: number? 
given: '(1 2 3 4 5) 
argument position: 1st 
other arguments...: 
0 

我還是新太剛剛在上週推出其方案,但它確實是frustrating..what我做錯了什麼?

回答

6

因爲(define (x . y) ...)相同(define x (lambda y ...)), 的identity下面的實現是相同的

(define (fun arg1) 
    arg1) 

(define fun 
    (lambda (arg1) 
    arg1) 

雖然list下面的實現是相同的

(define (fun . args) 
    args) 

(define fun 
    (lambda args 
    args) 

所以,當你申請(mean2 2 3 4 5)x是列表(2 3 4 5)(mean '(2 3 4 5))也包含所有參數到一個李st所以撥打sumlist變成(sumlist '((2 3 4 5)))。在sumlist你嘗試做(+ '(2 3 4 5) 0)這將無法正常工作,因爲+需要數字作爲參數,而不是列表。爲了解決這個問題,你需要定義mean2爲之一:

;; Just make an alias to mean 
(define mean2 mean) 

;; wrap mean 
(define (mean2 x) 
    (mean x)) 

;; use apply 
(define (mean2 . x) 
    (apply mean x)) ; apply undoes list 

我會使用的方法中出現的順序。有時候使用apply是最好的,但如果你只是別名或包裝,就不會。

+0

我討厭計劃,但你太棒了。謝謝 – user2968401

+3

@ user2968401能夠回答Scheme問題的人會傾向於愛Scheme,所以說你討厭Scheme不太可能讓你愛上他們。我知道一個事實,即當我回避OP說他們討厭Scheme的問題時。 –

+1

@ user2968401 - 這太遺憾了,因爲學習計劃可以是一種啓發性的體驗。部分原因是Scheme與傳統的「C風格」語言差別很大,在許多方面都更強大。你會想用一個很好的編輯器來修改括號(emacs,vim,也許是dr。racket?),並且還應該有一種不僅僅是「讓我盡最大努力通過這門課程」的態度 - 你似乎自從你發佈了這個:) –