DrRacket/Scheme:合同违规,预计会有多少?

use*_*401 1 scheme racket

所以我在方案中定义了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)))
Run Code Online (Sandbox Code Playgroud)

这就是我称之为功能的方式

(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
Run Code Online (Sandbox Code Playgroud)

上周我刚刚介绍它,我仍然是新的计划,但它真的很令人沮丧......我做错了什么?

Syl*_*ter 6

因为(define (x . y) ...)是相同的(define x (lambda y ...)),所以下面的实现identity是相同的

(define (fun arg1)
  arg1)

(define fun 
  (lambda (arg1)
     arg1)
Run Code Online (Sandbox Code Playgroud)

而以下实施list是相同的

(define (fun . args)
  args)

(define fun 
  (lambda args
     args)
Run Code Online (Sandbox Code Playgroud)

因此,当您应用(mean2 2 3 4 5) x列表时(2 3 4 5),(mean '(2 3 4 5))还会将所有参数包装到列表中,以便调用转换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
Run Code Online (Sandbox Code Playgroud)

我按照出现的顺序使用这些方法.有时使用apply是最好的,但如果你可以只是别名或换行.

  • @ user2968401能够回答计划问题的人都倾向于喜欢Scheme,所以说你讨厌Scheme不太可能让你感兴趣.我知道一个事实,当我避免回答OP说他们讨厌Scheme的问题时. (3认同)
  • 你们,别这么认真地对待我的评论。 (2认同)