Ocaml - 具有多态参数的构造函数



在玩具函数式语言的解释器中,我有一个expr类型,每个算术运算符和布尔运算符都有一个构造函数。我想将这种类型分解为:

type expr =
| Int of int
| BinaryArith of (int -> int -> int) * expr * expr
| Comparison of ('a -> 'a -> bool)   * expr * expr

但是,这不会键入,因为未定义'a类型参数。我可以完全参数化为'a expr,但是expr的单个实例将不再提供多态行为。

最终,我的愿望是将内置的比较运算符(<>>=等)传递给构造函数,所以我想在这里保留完整的多态性。

如果构造函数可以被视为函数,那么不可能实现的一个简单原因是 Hindley-Milner 类型系统仅支持"prenex"多态性。

我在这里做错了什么吗?有没有实现这种多态性的适当方法?

编辑:虽然接受者的答案解决了这个问题,但在其他答案和评论中提出了更好的设计。请务必阅读它们!

它并没有完全回答您的问题,但您可能希望让您的 AST 更具象征意义。例如:

type comparison_op = Eq | Ne | Lt | Gt | Le | Ge
type expr = ... | Comparison of comparison_op * expr * expr

然后,当您计算表达式时,您可以调用(=)(<=)等。

我不能排除这是 XY 问题的一个实例,但如果你真的需要它,从 OCaml 4.03 开始有可能有内联记录,即将记录类型(可以具有完全多态字段)直接声明为类型构造函数的参数,如下所示:

type expr =
| Int of int
| BinaryArith of (int -> int -> int)
| Comparison of { compare: 'a. 'a -> 'a -> bool }
let e = Comparison { compare = Pervasives.(=) }    

相关内容

最新更新