Scheme 中的列表要么是空列表(在某些 Lisps 中()
也称为),要么是一个 cons 单元格,其(也称为)是列表的一个元素,其(也称为)是列表的其余部分(即,另一个列表),或终止列表的原子。常规的终止符是空列表;被终止的列表被称为“正确的列表”。由任何其他原子终止的列表称为“不适当的列表”。该列表包含元素 1、2、3、4 和 5,并以 . 结尾。您可以通过以下方式构建它nil
car
first
cdr
rest
()
()
(1 2 3 4 5)
()
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
现在,当系统打印一个 cons 单元格时,一般情况是通过
(car . cdr)
例如,结果(cons 1 2)
打印为
(1 . 2)
由于列表是由 cons 单元格构建的,因此您也可以将这种表示法用于列表:
'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))
不过,这相当笨拙,所以大多数 lisps(据我所知)都有一个打印 cons 单元格的特殊情况:如果cdr
是一个列表(另一个 cons 单元格或()
),那么不要打印.
,也不要打印周围的括号cdr
(否则它会有,因为它是一个列表)。所以,如果你看到这样的结果
(1 2 3 . 4)
这意味着您有一个由 atom 终止的不正确列表4
。它具有结构
(1 . (2 . (3 . 4)))
现在的问题是:在您的代码中,列表构造哪里出错了?..
总是应该返回一个正确的列表,所以让我们看一下案例:第一个案例总是返回一个正确的列表(空列表):
((> (add1 start) stop) (quote ()))
第二种情况看起来它可以返回不是列表的东西(假设(sub1 stop) == (- stop 1)
):
((eq? (add1 start) stop) (sub1 stop))
现在,如果..
运行正常,那么第三种情况将始终返回一个正确的列表(因为(cons x y)
如果y
是正确的列表):
(else (cons start (.. (add1 start) stop)))
让你的第二个案例返回一个列表,你应该已经准备好了。