球拍匹配语义与null

Ant*_*dra 3 pattern-matching racket

我的问题是为什么以下模式返回,'match即使(make-tree 0 null null)显然不是null?

#lang racket
(define-struct tree (val left right))
(match (make-tree 1 (make-tree 0 null null) null)
  [(tree 1 null _) 'match]
  [_ 'no-match])
Run Code Online (Sandbox Code Playgroud)

我注意到在第一个模式中更改nullto会'()产生正确的(?)值.为什么会这样?是不是null'()等同?提前致谢.

Sor*_*ase 6

根据https://docs.racket-lang.org/reference/match.html,模式中的标识符具有以下规则:

id(var id)- 匹配任何内容,并绑定id到匹配的值.

在您的情况下,null不评估值.相反,它被识别为由在该位置匹配的值所遮蔽的标识符,即(make-tree 0 null null)


Ale*_*ing 5

如前所述,裸标识符将匹配任何内容,因为匹配模式中的标识符的目的是作为匹配的结果创建新的绑定。当然,null在 Racket 中不是关键字,它只是一个导出的绑定racket/base,所以它只是像往常一样被绑定。相比之下,'()是一个带引号的列表文字,显然可以被检测到match并进行相应的处理。

但是,能够动态比较值有时很有用,在这种情况下,这些值将绑定到标识符。在这种情况下,您可以使用==匹配扩展器,它将匹配与任意表达式的值进行比较。null如果您愿意,这将允许您使用:

#lang racket
(define-struct tree (val left right))
(match (make-tree 1 (make-tree 0 null null) null)
  [(tree 1 (== null) _) 'match]
  [_ 'no-match])
; => 'no-match
Run Code Online (Sandbox Code Playgroud)

当然,'()在这种情况下使用可能更清楚。