Types 变体定义中的多态变体限制

Types 变体定义中的多态变体限制,types,ocaml,polymorphic-variants,Types,Ocaml,Polymorphic Variants,假设我想在OCaml中建模一个简单的表达式类型: type expr = | `Int of int | `Str of string | `IntAdd of expr * expr | `StrAdd of expr * expr 是否可以将expr*expr中的expr限制为expr本身的特定构造函数(即,我希望IntExpr只允许'Int's)?我可以模仿这个模式 匹配,但在expr展开后会变得很麻烦。我可以吗 使用OCaml的类型系统来实现这一点 我尝试使用多态类型上限,如下所示:

假设我想在OCaml中建模一个简单的表达式类型:

type expr = 
| `Int of int
| `Str of string
| `IntAdd of expr * expr
| `StrAdd of expr * expr
是否可以将
expr*expr
中的
expr
限制为
expr
本身的特定构造函数(即,我希望
IntExpr
只允许'Int's)?我可以模仿这个模式 匹配,但在
expr
展开后会变得很麻烦。我可以吗 使用OCaml的类型系统来实现这一点

我尝试使用多态类型上限,如下所示:

type expr = 
| `Int of int
| `Str of string
| `IntAdd of [< `Int] * [< `Int]
| `StrAdd of [< `Str] * [< `Str]
type expr=
|”“Int/Int
|“字符串的Str
|`IntAdd of[<`Int]*[<`Int]
|`StrAdd of[<`Str]*[<`Str]

但编译器不接受这一点(如果IntAdd为[,变量'a是未绑定的。有什么诀窍可以做到这一点吗?

给定的示例非常简单,多态变体可以满足以下要求:

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]
如果您想要更多有趣的功能,如多态数据结构,则需要GADT:

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会影响错误消息的推理和可理解性,因此,如果您决定使用它们,请做好克服这些困难的准备。

这似乎是您在Haskell中使用GADT的目的:
data Expr a where{Int::Int->Expr Int;Str::String->Expr String;IntAdd::Expr Int->Expr Int->Expr Int;StrAdd::Expr String->Expr String->Expr String}
最后一个链接真的帮了大忙---谢谢!谢谢---GADTs似乎是一个正确的方法。旁注:第一个带有多态变体的示例并不像我喜欢的那样工作,因为
`Add(`String(“a”),`String(“b”))
编译时不存在任何问题。@Ibrahim,当然,多态变体允许通过设计进行无约束的构造。请注意,您所描述的值不会具有类型
expr
,并且在尝试将其用作
expr
时,而不是在构造时,您将得到一个类型错误。如果您ant早期的类型检查。