递归范围在Lisp中添加句号?(Recursive range in Lisp adds a per

2019-09-01 23:27发布

(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)

我不明白为什么会这样。 任何帮助表示赞赏

Answer 1:

方案A列表要么是空列表()也称为nil在一些的Lisp)或cons单元,其car (也称为first )是列表的元素和其cdr (也称为rest )或者是该列表的其余部分(即,另一列表),或终止列表中的原子。 常规的终止子是空列表() ; 通过封端的列表()被说成是“适当的列表”。 通过任何其它原子封端的列表被称为“不当列表”。 列表(1 2 3 4 5)包含1,2,3,4和5,并且由终止元件() 您可以通过它构建

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))

现在,当系统打印 cons单元,一般情况下是打印出来

(car . cdr)

例如,结果(cons 1 2)被打印为

(1 . 2)

由于名单是建立利弊细胞,就可以使用这个符号的列表太:

'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))

这是非常笨拙,虽然如此,大多数的Lisp(所有我知道的),具有打印利弊细胞一种特殊情况:如果cdr是一个列表(无论是另一个缺点细胞,或()那么就不能打印. ,不打印的圆括号括起来的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 xy)是一个适当的列表,如果y是):

(else (cons start (.. (add1 start) stop)))

让你的第二个案例返回一个列表,你应该准备就绪。



Answer 2:

你的表达(sub1 stop)需要读取(list (sub1 stop))

为了cons建立一个适当的列表,第二个元素必须是一个列表本身。 因此,你的功能..应该返回某种类型的列表,每个cond条款。



Answer 3:

取下COND的这部分

 ((eq? (add1 start) stop) (sub1 stop))

这是造成过早结束。



文章来源: Recursive range in Lisp adds a period?
标签: lisp scheme