因此,通过一系列有趣的事件,我下载了FParsec源代码并尝试构建它。不幸的是,它与新的 1.9.9.9 不兼容。我解决了简单的问题,但是有几个受歧视的工会仍然不起作用。
具体来说,Don Syme 的帖子解释了包含类型项的可区分联合obj
或->
不会自动获得相等或比较约束,因为对象不支持比较并且函数也不支持相等。(不清楚自动生成的相等/比较之前是否有问题,但现在它们不再生成,代码甚至无法编译。)
以下是有问题的 DU 的一些示例:
type PrecedenceParserOp<'a,'u'> =
| PrefixOp of string * Parser<unit,'u> * int * bool * ('a -> 'a)
| others ...
type ErrorMessage =
| ...
| OtherError of obj
| ...
以下是违规用途:
member t.RemoveOperator (op: PrecedenceParserOp<'a, 'u>) =
// some code ...
if top.OriginalOp <> op then false // requires equality constraint
// etc etc ...
或者,对于比较约束
let rec printMessages (pos: Pos) (msgs: ErrorMessage list) ind =
// other code ...
for msg in Set.ofList msgs do // iterate over ordered unique messages
// etc etc ...
据我所知,Don 用唯一的 int 标记每个实例的解决方案是实现自定义相等/比较约束的正确方法(或者可能是唯一的 int 元组,以便可以对 DU 的各个分支进行排序)。但这对于DU的用户来说是不方便的。现在,DU 的构建需要调用一个函数来获取下一个标记。
有没有办法隐藏标签获取并向库的用户提供相同的构造函数?也就是在不改变接口的情况下改变实现?这一点尤其重要,因为它看起来(根据我对代码的理解)PrecedenceParserOp
是一种公共类型。