什么是报价? (引号aaa)和aaa彼此不同

时间:2019-06-16 09:36:52

标签: scheme lisp common-lisp racket

(define (delete-list my-list element)
  (if (null? my-list)
      '()
      (if (eqv? (car my-list) element)
          (cdr my-list)
          (append (list (car my-list))
                  (delete-list (cdr my-list) element)))))

(delete-list '('aaa 'bbb) 'aaa)
; ==> ('aaa 'bbb)

该代码为什么不输出('bbb)? 如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

  1. 您需要搜索'aaa,而不是aaa
  2. 您需要测试是否平等

示例:

(define (delete-list my-list element)
  (if (null? my-list)
      '()
      (if (equal? (car my-list) element)
          (cdr my-list)
          (append (list (car my-list))
                  (delete-list (cdr my-list) element)))))

?  (delete-list '('aaa 'bbb) ''aaa)
=> ((quote bbb))

答案 1 :(得分:3)

方案有3个通用的相等谓词过程。 eq?检查指针是否相等,eqv?检查原始类型数字和字符是否具有相同的值。 equal?检查值是否相同。

列表'(a b)是一个复杂的结构,因此(eq? '(a b) '(a b)) ; ==> #f * 1则为(equal? '(a b) '(a b)) ; ==> #t。如果要比较列表,则此过程需要使用equal?

引号创建一个结构。因此,代码'x表示(quote x),而'(a b)表示(quote (a b)),无论它出现在数据内部还是代码中。评估程序将停在第一个位置,因此'('aaa 'bbb)变为(quote ((quote aaa) (quote bbb))),并且由于只有第一个quote是代码,因此结果是数据((quote aaa) (quote bbb)),实现可能将其可视化为{{1 }}。要在最后一个列表中创建元素,您需要将评估结果为('aaa 'bbb)(quote aaa)),因此您需要传递'aaa。您可能已经了解,求值''aaa是列表数据'aaa,您需要(quote aaa)来测试它们:

equal?

其他内容

作为一种样式,由于您使用嵌套的(eqv? ''aaa ''aaa) ; ==> #f *1 (equal? ''aaa ''aaa) ; ==> #t ,因此可以改用一个if使感觉平整。

将一个元素添加到列表的开头时,应使用condcons(cons 'a '(b c))更为简洁,后者最终会(append (list 'a) '(b c))

添加这些内容后,我会得到:

(cons (car (list 'a)) '(b c))

请注意,如我的测试所示,您的设计仅删除了第一次出现的问题。

* 1常量数据可能会被重用。因此,由于无法更改常量数据,因此某些实现在(define (delete-list my-list element) (cond ((null? my-list) '()) ((equal? (car my-list) element) (cdr my-list)) (else (cons (car my-list) (delete-list (cdr my-list) element))))) (delete-list '('aaa 'bbb 'ccc 'bbb) ''bbb) ; ==> ('aaa 'ccc 'bbb) (delete-list '(aaa bbb ccc bbb) 'bbb) ; ==> (aaa ccc bbb) 上返回#t,因此对于实现来说,重用一个值是安全的。一些实现仅在编译时执行此操作,但在解释时会重新创建常量数据。

答案 2 :(得分:1)

您不需要在引号内引用内容。因此,只需使用'(aaa bbb)作为输入即可。