变体定义中的多态性变体限制
Polymorphic variant restriction in the variant definition
假设我想在 OCaml 中建模一个简单的表达式类型:
type expr =
| `Int of int
| `Str of string
| `IntAdd of expr * expr
| `StrAdd of expr * expr
是否可以将 expr * expr
中的 expr
限制为 expr
本身的特定构造函数(即我希望 IntExpr
只允许“Int”)?我可以用模式模仿这个
匹配,但在 expr
扩展后变得很麻烦。我能以某种方式
使用 OCaml 的类型系统来实现这个?
我尝试使用多态类型上限如下:
type expr =
| `Int of int
| `Str of string
| `IntAdd of [< `Int] * [< `Int]
| `StrAdd of [< `Str] * [< `Str]
但编译器不接受这个(消息 In case IntAdd of [< Int ] * ([< Int ] as 'a) the variable 'a is unbound
)。有什么技巧可以使它起作用吗?
给定的示例足够简单,多态变体就足够了:
type int_expr = [`Int of int | `Add of int_expr * int_expr]
type string_expr = [`String of string | `Concat of string_expr * string_expr]
type expr = [int_expr | string_expr]
如果你想要更有趣的特性,比如多态数据结构,GADTs 是必要的:
type _ expr =
| Int : int -> int expr
| Add : int expr * int expr -> int expr
| String : string -> string expr
| Concat : string expr * string expr -> string expr
| Pair : 'a expr * 'b expr -> ('a * 'b) expr
| Fst : ('a * 'b) expr -> 'a expr
| Snd : ('a * 'b) expr -> 'b expr
错误消息的推理和可理解性受到 GADT 的影响,因此如果您决定使用它们,请准备好克服这些困难。
假设我想在 OCaml 中建模一个简单的表达式类型:
type expr =
| `Int of int
| `Str of string
| `IntAdd of expr * expr
| `StrAdd of expr * expr
是否可以将 expr * expr
中的 expr
限制为 expr
本身的特定构造函数(即我希望 IntExpr
只允许“Int”)?我可以用模式模仿这个
匹配,但在 expr
扩展后变得很麻烦。我能以某种方式
使用 OCaml 的类型系统来实现这个?
我尝试使用多态类型上限如下:
type expr =
| `Int of int
| `Str of string
| `IntAdd of [< `Int] * [< `Int]
| `StrAdd of [< `Str] * [< `Str]
但编译器不接受这个(消息 In case IntAdd of [< Int ] * ([< Int ] as 'a) the variable 'a is unbound
)。有什么技巧可以使它起作用吗?
给定的示例足够简单,多态变体就足够了:
type int_expr = [`Int of int | `Add of int_expr * int_expr]
type string_expr = [`String of string | `Concat of string_expr * string_expr]
type expr = [int_expr | string_expr]
如果你想要更有趣的特性,比如多态数据结构,GADTs 是必要的:
type _ expr =
| Int : int -> int expr
| Add : int expr * int expr -> int expr
| String : string -> string expr
| Concat : string expr * string expr -> string expr
| Pair : 'a expr * 'b expr -> ('a * 'b) expr
| Fst : ('a * 'b) expr -> 'a expr
| Snd : ('a * 'b) expr -> 'b expr
错误消息的推理和可理解性受到 GADT 的影响,因此如果您决定使用它们,请准备好克服这些困难。