为什么list-ref适用于pair

时间:2017-03-12 06:39:08

标签: list scheme racket

在以下代码中:

(define l (cons 1 2))
l
(list? l)
(pair? l)
(list-ref l 0)  ; works;
(list-ref l 1)  ; DOES NOT WORK;

输出:

'(1 . 2)
#f
#t
1
Error: list-ref: index reaches a non-pair
  index: 1
  in: '(1 . 2)

如果l不是列表,为什么(list-ref l 0)有效。否则,为什么(list-ref l 1)不起作用。这种行为似乎是不一致和混乱创建。

函数carcdr也可以工作,分别返回1和2。如果这不是列表,为什么cdr可以工作。人们希望car返回1.2而不只是1。

2 个答案:

答案 0 :(得分:4)

来自the documentation

  

lst参数实际上不必是列表; lst必须仅以至少(add1 pos)对的链开始。

这意味着只要索引小于lst为非对的第一对的索引,cdr参数就被允许为不合适的列表。

答案 1 :(得分:4)

列表只是链接在一起的很多对,终止于空列表。例如,(list 1 2 3)相当于(cons 1 (cons 2 (cons 3 '())))

没有理由遍历整个列表以检查l是否是列表,因此只要它看起来像列表,方案就不关心它是否在一个列表中终止空列表。 list-ref基本上定义如下:

(define (list-ref lyst index)
    (cond ((= index 0) (car index))
          (else (list-ref (cdr lyst) (- index 1)))))

当然,尝试运行(car 2)

时会遇到错误

至于另一个问题,carcdr只返回一对中的第一个元素和一对中的第二个元素。