Scheme 为什么不';这两个不相等吗?
我正在准备考试,我注意到这个问题:Scheme 为什么不';这两个不相等吗?,scheme,racket,Scheme,Racket,我正在准备考试,我注意到这个问题: Define an object x so that (eq? (car x) (cdr x)) returns #t 我最初认为这会很简单cdr x是一个列表,而car x是一个元素,所以我猜x中的第一个元素应该是一个与x的尾部相等的列表。所以我想到了 (define x (list (list 1) 1)) 在DrRacket中调用car x会导致(列表1),而cdr x也是如此,但当我尝试调用(eq?(car x)(cdr x))时,结果是#f 我到
Define an object x so that (eq? (car x) (cdr x)) returns #t
我最初认为这会很简单cdr x
是一个列表,而car x
是一个元素,所以我猜x中的第一个元素应该是一个与x的尾部相等的列表。所以我想到了
(define x (list (list 1) 1))
在DrRacket中调用car x
会导致(列表1)
,而cdr x
也是如此,但当我尝试调用(eq?(car x)(cdr x))
时,结果是#f
我到底错过了什么?正确答案是什么?以您使用
(列表1)
的示例为例:
(定义x
(让([尾部(列表1)])
(反对)(反对)
更简单的例子是:
(定义x'(());同:(定义x(cons(list)(list)))
这取决于只有一个空列表对象的事实(即,(eq?(list 1)(list 1))
始终为false,(eq?(list)(list))
始终为true)
在一个相关的注释中(尽管就您的测试而言有些过头),您是否知道您还可以制作一个对象
x
,以便(car x)
和(cdr x)
引用与x
相同的对象
(定义x(使用输入字符串“#0=(#0#.#0#)”读取调用))
:-p我们可以得到的
汽车和cdr
不是一个列表。这是一双
使用cons
创建对,例如:
(定义val(列表1))
(定义val对(cons val val))
(list(list 1)1)
与(cons(list 1)(list 1))
相当,其中list
被调用两次,每次都在内存中返回一个新的、单独的对象,尽管值相等。但是eq?
仅对同一内存对象返回true
因此,虽然您的想法是合理的,从价值角度来看,这里实际比较的不是价值,而是相同性,就像内存对象的“指针相等性”一样。问题是为什么
(define x (list (list 1) 1))
(eq? (car x) (cdr x))
给出结果#f
首先,让我们使用cons
而不是list
(list 1) is the same as (cons 1 '())
(list a b) is the same as (cons a (cons b '())
你的例子变成:
(define x (cons (cons 1 '())
(cons 1 '()))
(eq? (car x) (cdr x))
因为上面有两次表达式(cons1'())
,所以让我们添加一个索引(这样我们就可以引用表达式了)
(define x (cons (cons_1 1 '())
(cons_2 1 '()))
(eq? (car x) (cdr x))
这表明
(car x) returns the result of (cons_1 1 '())
(cdr x) returns the result of (cons_2 1 '())
调用(cons A b)
将在内存中分配一个小数据结构,该结构(大致)如下所示:
<tag-for-pairs> <pointer-to-the-value-a> <pointer-to-the-value-b>
这意味着调用(cons_1’())
和(cons_2 1’())
将分配两对,每对在内存中都有自己的位置(地址)
调用(eq?x y)
只会比较两个对象x
和y
的位置(地址)。这意味着即使两对对象的内容相等,比较(eq?(cons_1’())(cons_2 1’())将返回false。(eq?(列表1)(列表1))=>f