在this回答中,将元信息“附加”到类型的建议方法是使用记录:
type _foo = ...
and foo = {n:_foo; m:meta}
但如果我有多个类型,我想用元信息包装怎么办?显然,记录类型中的所有字段名称必须具有不同的名称,并且写入:
type _foo = ...
and foo = {n:_foo; m:meta}
...
type _fooX = ...
and fooX = {nX:_fooX; mX:meta}
似乎多余:/。类是解决这个问题的唯一方法吗?如果可能的话,我想避免处理课程。
答案 0 :(得分:5)
您可以使用参数化类型。
type 'a wrapped = { base: 'a; extra: meta }
答案 1 :(得分:3)
Jeffrey的解决方案是正确的,并且可以完美地扩展到递归类型。
type location
type 'a loc = { a : 'a; loc : location }
type exp = Int of int | Add of exp loc * exp loc
仍然可以使用您之前的两次定义类型, 如下:
type exp_data = Int of int | Add of exp * exp
and exp = exp_data loc
最后,稍微不同的风格是使用“开放递归”,即仅使用自由参数而不是递归出现来定义“去递归类型”open_exp
。然后你可以通过修复点来获取递归类型;你可以采用不同的固定点,一个没有附加信息,一个有位置交错,例如。这是在递归站点插入信息的通用构造,它的术语级别对应允许在递归函数(memoization,profiling,debug等)中编织不同的东西。
type 'e open_exp = Int | Add of 'e * 'e
type simple_exp = Simple of simple_exp open_exp
type located_exp = Loc of located_exp loc open_exp