andmap和null?返回false

3
我想确定一个列表是否只包含nullnull?似乎是显而易见的选择:
> (null? null)
#t

但是通过andmap映射它并没有达到我的预期:

> (andmap null? '(null))
#f

我是否误解了null?或者andmap?我是Racket的新手,但是根据文档来看,这似乎完全不正确。


1
就我个人而言,作为一名曾经从事C/C++编程的人来说,“null”和“null?”这两个术语对我来说有些误导性。我更喜欢使用“'()”或“(list)”来表示空列表,并使用“empty?”作为谓词。 - Greg Hendershott
@GregHendershott 很好的观点!我还没有遇到过empty?,但这对我来说更有意义。 - Aaron Dufour
2个回答

8
你的问题在于'(null)不是包含null(即空列表)的列表。这里有几个可行的选项:
  • (andmap null? '(()))
  • (andmap null? `(,null))或者(andmap null? (quasiquote (unquote null)))
  • (andmap null? (list null))
关于发生了什么的解释:标识符null绑定到表示空列表的值。当你使用'null时,这相当于(quote null),它的意思是“给我一个代表该标识符的符号,而不是它所代表的内容”(类似于自然语言中的引用)。
你可以通过使用表示null的字面量'()或使用quasiquoteunquote来“逃回”Racket,从而避免这种情况。
有关引用的更多信息,请参见指南条目

谢谢。现在这个意思清楚多了。 - Aaron Dufour

4
问题不在于 andmap 或者 null?,而是你构建列表的方式有误。实际上这个列表:'(null) 等同于这个:(list 'null)
(equal? '(null) (list 'null))
=> #t

'nullnull不是同一件事情:

(equal? 'null null)
=> #f

因此,我们需要一种正确的方式在列表中表示空值。以下任何一种方式都可以:

(andmap null? '(()))
=> #t
(andmap null? (quote (())))
=> #t
(andmap null? (list '()))
=> #t
(andmap null? (list null))
=> #t
(andmap null? `(,null))
=> #t
(andmap null? (quasiquote (unquote null)))
=> #t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接