我想在Lisp中创建以下列表。
((lambda(x) (cons x x)) (cons'A 'B))
创建此列表,但
((lambda(x y) (cons x y)) (cons'A 'B) (cons 'A 'B))
和
(cons (cons 'A 'B) (cons 'A 'B))
不要创建列表。
我的挑战是为什么!?第一个命令如何创建此列表而其他命令没有?任何细节?
答案 0 :(得分:4)
答案 1 :(得分:4)
您想要创建A和B的cons
:
(cons 'A 'B)
然后你想从另一个缺点中引用它两次。因此,如果x
是对现有cons
的引用,则需要
(cons x x)
结束,我们得到
(let ((x (cons 'A 'B)) (cons x x))
或等效
((lambda (x) (cons x x)) (cons 'A 'B))
如果您执行(cons 'A 'B)
两次,则会创建两个单元格:
A 乙
A 乙
,其中cons
将包含一个指向第一个链接,另一个指向第二个链接。
(使用lambda
引用它们是一种毫无意义的混淆;具有lambda
形式的示例的点是您使用x
两次。表格
((lambda (x y) (cons x y)) (cons 'A 'B) (cons 'A 'B))
只是一种非常繁琐的写作方式
(cons (cons 'A 'B) (cons 'A 'B))
而在最初的例子中,只有一个(cons 'A 'B)
的实例,你希望能够引用两次。)
本练习的目的是说明“表面”对等与身份之间的区别。包含相同值的两个列表仍然是两个不同的列表,而对同一列表的两个引用是相同的。正如@sde提示的那样,这对理解比较有所帮助;原型示例是equal
对于包含相同值的不同列表(当然还有相同的列表)是正确的,而eql
仅在其参数实际上相同时才为真(即它们引用到同一个对象)。