方案中的可选参数和点

The*_*ire 6 scheme optional-parameters racket

所以,我试图看看可以接受任意数量的参数的函数是如何工作的?

我试过这个

(define (plus x . xs)
  (if 
   (null? xs) x
   (plus (+ x (car xs)) . (cdr xs))))
(plus 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)

但似乎它实际上并没有将cdr应用于xs,而是在调试器中通过它时传递((2 3 4)).所以我尝试了这个

(define (plus* x . xs)
  (if 
   (null? xs) x
   (let ((h (car xs))
         (t (crd xs)))            
     (plus* (+ x h) . t))))
Run Code Online (Sandbox Code Playgroud)

思考:"哈,我想看到你现在通过cdr",但我得到一个错误:"应用程序:错误的语法(非法使用`.')in :(加*(+ xh).t)"

到底是怎么回事?

(我可以通过以下方式获得加入工作的版本

(define (add . xs)
     (foldl + 0 xs))
Run Code Online (Sandbox Code Playgroud)

甚至

(define (plus x . xs)
  (if 
   (null? xs) x
   (apply plus (cons (+ x (car xs))  (cdr xs)))))
Run Code Online (Sandbox Code Playgroud)

所以,添加不是问题,事情是多么有效.)

Eli*_*lay 7

您的上一个版本是将数字列表作为输入传递的正确方法plus- 您必须使用apply这样做.(好吧,要么就是这样,要么就像你所做的那样避免整个事情foldl.)在应用程序中使用点不是你认为它应该做的 - 它使程序读取不同.

  • `(x.y)`被读作一个cons单元格,其`car`中的`x`和cdr中的`y` - 也就是说,它不是一个正确的列表.类似地,`(x.(y))`是一个在其`car`中带有`x`的cons单元格,在它的`cdr`中有一个列表`(y)` - 所以它与读取`(xy)相同`.所以当你写`(加x.(cdr t))`时,它就像你写'(加上x cdr t)`一样,这解释了你得到的令人困惑的结果. (3认同)