如何在 Typed Racket 中定义 Union 多态数据结构的实例?

How to define Union polymorphic data structure's instance in Typed Racket?

来自Typed Racket Guide,要定义联合类型,只需使用(define-type Some-Type (U Type1 Type2))

要定义多态数据结构,请使用 (define-type (Opt a) (U ...))

我想定义一个多态二叉树

(define-type (Tree a) (U (Leaf a) Node))
(struct (a) Leaf ([val : a]))
(struct Node ([left : Tree] [right : Tree]))
(define t1 (Leaf 5))
(define t2 (Leaf 8))
(define t3 (Node t1 t2))

我想知道为什么 t1 的类型是 Leaf 而不是 Tree,如何使它成为 Tree

> t1
- : (Leaf Positive-Byte)
#<Leaf>

请参阅有关子类型的参考资料 (https://docs.racket-lang.org/ts-guide/types.html#%28part._.Subtyping%29)。基本上,当您使用联合类型时,Racket 不会破坏旧类型。例如,您可以定义类型 (U String Number),但 StringNumber 仍然可用。 1 仍会被识别为 Number,但您可以在任何需要 (U String Number) 的地方使用它,因为 Number(U String Number).[=27 的子类型=]

同样,t1Leaf,因此 Racket 报告 t1Leaf 并没有错。但是,LeafTree 的子类型,因此 t1 可以用在需要 Tree 的地方。

当你这样做时:

(define-type (Tree a) (U (Leaf a) Node))

您将 Tree 定义为类型构造函数。您不应该将 Tree 本身视为一种类型,仅将 (Tree Some-Concrete-Type) 视为一种类型。所以将其重命名为 Treeof:

(define-type (Treeof a) (U (Leaf a) Node))
(struct (a) Leaf ([val : a]))
(struct Node ([left : Treeof] [right : Treeof]))

现在问题更清楚了。节点结构需要 Treeof,但是什么树?你要的是这个:

(define-type (Treeof a) (U (Leaf a) (Node a)))
(struct (a) Leaf ([val : a]))
(struct (a) Node ([left : (Treeof a)] [right : (Treeof a)]))

现在你的例子有效了:

#lang typed/racket
(define-type (Treeof a) (U (Leaf a) (Node a)))
(struct (a) Leaf ([val : a]))
(struct (a) Node ([left : (Treeof a)] [right : (Treeof a)]))
(define t1 (Leaf 5))
(define t2 (Leaf 8))
(define t3 (Node t1 t2))