如何用点符号递归?

时间:2017-05-18 16:11:36

标签: scheme

我有一个功能:

(define (func lst . conditions)
    ; do something
    (func (cdr lst) conditions))

但第二次,似乎funcconditions包含在列表中,然后我无法正确使用其内容(功能)。我应该如何通过conditions以便该函数将其处理方式与对func的初始调用处理方式相同?

2 个答案:

答案 0 :(得分:0)

您的描述并不完全准确。引用R5RS,第4.1.4章(强调我的):

(<variable1> ... <variablen> . <variablen+1>)如果空格分隔的句点在最后一个变量之前,则该过程需要n个或多个参数,其中n是句点之前的正式参数的数量(必须至少有一个) )。存储在最后一个变量的绑定中的值将是在所有其他实际参数与其他正式参数匹配后剩余的实际参数的新分配列表 < / p>

换句话说,conditions从一开始就是一个列表。通过定义类似以下内容来检查:

(define (func lst . conditions)
  (display conditions) (newline))

正如Alexis King正确指出的那样,您需要使用apply再次“打开”列表:

(apply func (cdr lst) conditions)

答案 1 :(得分:0)

它不是点符号,而是休息参数。基本上其余的参数都被列入一个列表。

与rest参数相反的是一个过程,它将列表作为最后一个参数,就好像元素是函数的额外参数一样。一个通用的存在为apply

(define (double-list . e)
  (if (null? e)
      '()
      (list* (car e) 
             (car e)
             (apply helper (cdr e)))))

但是,如果你有一个10元素列表,你最终会生成10个递减大小的列表,这些列表只能在作为参数传递之前存在一段时间。保持第一个列表会更好,可以通过帮助程序来完成:

(define (double-list . e)
  (define (helper e)
    (if (null? e)
        '()
        (list* (car e) 
               (car e)
               (helper (cdr e)))))
  (helper e))

它的工作方式相同,但使用的内存较少,因为帮助程序只是迭代第一个创建的列表,而不是为每次迭代创建一个新列表。