在 PL Racket 中使用与用户定义类型的匹配

Using match with user defined types in PL Racket

以下 PL 代码在 #lang pl 下不起作用:

根据 Alexis Kings 的回答编辑代码

(define-type BINTREE
  [Leaf Number]
  [Node BINTREE BINTREE])

(: retrieve-leaf : BINTREE -> Number)
(define (retrieve-leaf btree)
  (match btree
  [(Leaf number) number])

我想达到的效果如下:

  1. 接收 BINTREE 作为输入
  2. 检查树是否只是一片叶子
  3. Return叶子数值

这可能是一个基本问题,但我将如何解决这个问题?


编辑: 如果使用 cases 而不是 match,以上内容似乎有效。 这是为什么?

我认为您的方向是正确的,但是您的 match 语法不正确。它应该是这样的:

(: retrieve-leaf : BINTREE -> Number)
(define (retrieve-leaf btree)
  (match btree
    [(Leaf number) number]))

匹配模式子句必须在 match 形式内。此外,number 只是一个绑定,而不是一个过程,因此不需要在括号中。

如您所见,matchcases 是两个相似但不同的对象 事物。第一个用于一般球拍值,第二个是 用于您用 define-type 定义的事物。很遗憾, 它们在任何一个方向上都不能很好地混合,所以如果你有一个定义的类型 那么你需要使用 cases.

至于原因,有点复杂...有一件事是 pl 语言在 match 足够强大之前就已开发完成 方便地处理任意值。现在可以,但不能 可以很容易地调整以完成案例的工作:define-type 背后的想法 是通过强制使用 just 来简化编程 cases 对于这样的值 --- 没有字段访问器,没有谓词 对于变体(仅针对整个类型),当然没有突变。 不过,只需 cases 就可以做任何您需要的事情。如果你 仔细阅读,核心思想是模仿 HM 中的不相交联合类型 像 ML 和 Haskell 这样的语言,并且只有 cases 模式匹配 可用,许多功能很容易启动,因为只有一种方法 对付他们。

match 和 Typed Racket 更接近能够做这些事情, 但它仍然不够强大,无法完成所有这些——这是 为什么 cases 在不久的将来会与 match 分开。

附带说明一下,这与我想要的相反——我知道这 经常是一个混乱点,所以我很乐意只使用 match 始终。也许我会在某个时候打破并破解东西以便 cases又叫match,分支的内容会 用于猜测您是否真的需要真正的 matchcases 版本。但这确实是一个粗略的 hack。