(define ..
(lambda (start stop)
(cond ((> (add1 start) stop) (quote ()))
((eq? (add1 start) stop) (sub1 stop))
(else (cons start (.. (add1 start) stop))))))
我定义了一个简单的范围函数。 意图是
(.. 1 5) --> (1 2 3 4)
相反,我的元组中添加了一个奇怪的时期,我不明白为什么:
(.. 1 5) --> (1 2 3 . 4)
我不明白为什么会这样。任何帮助表示赞赏
答案 0 :(得分:15)
Scheme中的列表是空列表()
(在某些Lisp中也称为nil
),或者是car
(也称为first
的缺点列表)是列表的一个元素,其cdr
(也称为rest
)是列表的其余部分(即另一个列表),或者是终止列表的原子。传统的终结符是空列表()
;被()
终止的列表被称为“正确列表”。被任何其他原子终止的列表称为“不正确的列表”。列表(1 2 3 4 5)
包含元素1,2,3,4和5,并由()
终止。您可以通过
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
现在,当系统打印一个缺点单元时,一般情况是通过
打印它(car . cdr)
例如,(cons 1 2)
的结果打印为
(1 . 2)
由于列表是由增量单元格构建的,因此您也可以将此表示法用于列表:
'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))
但是,这是相当笨重的,所以大多数lisps(我所知道的)都有一个打印cons单元格的特殊情况:如果cdr
是一个列表(另一个cons单元格,或()
),然后不打印.
,并且不打印cdr
的周围括号(否则它将具有,因为它是一个列表)。所以,如果你看到像这样的结果
(1 2 3 . 4)
这意味着你有一个由原子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)))
是正确的列表):
{{1}}
让你的第二个案例返回一个列表,你应该全部设置。
答案 1 :(得分:1)
您的表达式(sub1 stop)
需要阅读(list (sub1 stop))
为了cons
建立一个正确的列表,第二个元素本身需要是一个列表。因此,您的函数..
应该返回每个cond
子句的某种类型的列表。
答案 2 :(得分:1)
删除cond的这部分
((eq? (add1 start) stop) (sub1 stop))
这导致过早完成。