types - 变体定义中的多态变体限制

标签 types ocaml polymorphic-variants

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

type expr = 
| `Int of int
| `Str of string
| `IntAdd of expr * expr
| `StrAdd of expr * expr

是否可以限制exprexpr * exprexpr 的特定构造函数本身(即我希望 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]

如果您想要更多有趣的功能,例如多态数据结构,则需要 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 会影响错误消息的推理和可理解性,因此,如果您决定使用它们,请准备好克服这些困难。

关于types - 变体定义中的多态变体限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53235639/

相关文章:

mongodb - 如何更改mongodb数组值的数据类型?

haskell - “惯用的” haskell 型不等式

optimization - 如何通知优化器 NonZeroU32::get 永远不会返回零?

ocaml - 模块何时重新声明或别名?

ocaml - 可以用frama-c做头文件分析吗?

pattern-matching - 使用 GADT 建模语法,但类型参数无法统一

functional-programming - 在 F# 中模拟多态变体?

scala - 如何在 Scala 中为泛型类型提供默认类型类?

debugging - 从 emacs 运行时,ocaml 调试器找不到核心