当我cons
对两个原子做 a 时,我.
在两者之间得到 a。
1]=>(cons 'one 'two)
;Value 1: (one . two)
为什么我要找.
运营商。它有什么意义吗?我正在使用mit-scheme
.
我看过这个 stackoverflow 链接,但不清楚。
更新:Little Schemercons
中的定义指出,
接受两个参数,第一个是任何 S 表达式,第二个是任何列表。cons
当我cons
对两个原子做 a 时,我.
在两者之间得到 a。
1]=>(cons 'one 'two)
;Value 1: (one . two)
为什么我要找.
运营商。它有什么意义吗?我正在使用mit-scheme
.
我看过这个 stackoverflow 链接,但不清楚。
更新:Little Schemercons
中的定义指出,
接受两个参数,第一个是任何 S 表达式,第二个是任何列表。cons
cons
当cdr
部件本身不是单元cons
格或空列表时,点就是 Scheme 显示单元格的方式。在这种情况下,点不是运算符,例如:
(cons 1 2)
=> '(1 . 2) ; a cons pair, a.k.a. a cons cell
(cons 1 (cons 2 3))
=> '(1 2 . 3) ; not a proper list, it doesn't end in '()
如果该cdr
部分是一个cons
单元格或空列表'()
,那么我们有一个列表:
(cons 1 '())
=> '(1) ; a proper list, ends in '()
(cons 1 (cons 2 '()))
=> '(1 2) ; a proper list, ends in '()
The Little Schemer 中的定义是一种简化,实际上cons
它的每个参数都可以采用任何类型的值。按照惯例,如果第二个参数是一个列表,它将被视为一个列表并照此显示,否则它是一个普通的旧cons
单元格,并且点在那里提醒您这一点。
该过程cons
创建了一个指向所提供的两个参数的“cons 单元格”。
一个 cons 单元是一对指针,一个列表是单个 cons 单元或一系列 cons 单元,其第二个指针指向另一个 cons 单元,最后一个单元的第二个指针指向另一个对象。
注意:为了简单起见,我使用“对象”这个词,而不是在编程意义上。
在正确的列表中,最后一个 cons 单元格的第二个指针指向一个空列表。
在不正确的列表中,最后一个 cons 单元格的第二个指针指向一个不是空列表的对象。
注意2:“空列表”()
是scheme中的唯一值,与列表不同,在普通lisp中它等于nil,nil在scheme中不存在。
+-----+-----+
| | |
| | |
+--+--+--+--+
| |
| |
v v
obj obj
一个缺点细胞
+-----+-----+ +-----+-----+ +-----+-----+
| | +---->+ | +---->+ | |
| | | | | | | | |
+--+--+-----+ +--+--+-----+ +--+--+--+--+
| | | |
| | | |
v v v v
0 1 2 3
(0 1 2 . 3) -> (0 . (1 . (2 . 3)))
不合适的清单
+-----+-----+ +-----+-----+ +-----+-----+
| | +---->+ | +---->+ | +----> ()/nil
| | | | | | | | |
+--+--+-----+ +--+--+-----+ +--+--+-----+
| | |
| | |
v v v
0 1 2
(0 1 2) -> (0 . (1 . (2 . () )
适当的清单
点(当在 repl 中看到时)用于表示列表的最终指针指向的对象不是空列表,因此它是不正确的列表。
这是我至少从普通 lisp 的理解,尽管我确信它可以转化为大多数其他 lisp(我认为 Clojure 是不同的(如果你认为它是一个 lisp))。
~
小计划者在撒谎。cons
可以将任何类型作为其第一个和第二个参数。您始终可以使用带引号的结构创建一对,例如'(1 . 8)
.
没有专门用于制作列表的数据结构,因此 Scheme 有一个技巧。他们将列表定义为空列表或以cons
列表为cdr
. 这'(1 . (2 . (3 . ())))
是一个列表,如果您评估它,Scheme repl 将打印(1 2 3)
回来。如果您评估'(1 2 3)
,读者将'(1 . (2 . (3 . ())))
在 Scheme 解释器评估它之前将输入代码转换为。以 结尾的列表'()
称为正确列表,因为它在最后两个元素之间没有点。例如。'(1 . (2 . (3 . 4))) ; ==> (1 2 3 . 4)
如果你给第二个参数一个正确的列表,结果总是一个正确的列表,你不会看到任何点。