所以我在方案中定义了3个函数,sumlist将列表中的所有数字相加,并且mean给出了列表的平均值。 mean2调用意味着并做同样的事情,但我得到一个错误。它说错误来自sumlist函数。
(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
我还是新手,上周刚刚介绍过它的方案,但这真的令人沮丧......我做错了什么?
答案 0 :(得分: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))
也会将所有参数包装到列表中,以便对sumlist
的调用变为(sumlist '((2 3 4 5)))
。在汇总表中,您尝试执行(+ '(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是最好的,但如果你可以使用别名或换行则不行。