1

因此,通过一系列有趣的事件,我下载了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是一种公共类型。

4

2 回答 2

2

您为 FParsec 下载了什么源代码?我从 FParsec BitBucket 存储库中获取了最新版本,我根本不需要对 FParsec 源代码进行任何更改就可以在 VS 2010 RC 中编译它。

编辑:我收回了。我确实从 InterpLexYacc 和 InterpFParsec 示例项目中得到了构建错误,但核心 FParsec 和 FParsecCS 项目构建得很好。

于 2010-02-18T19:19:28.903 回答
1

您可以做的一件事是添加[<CustomEquality>][<CustomComparison>]属性并定义您自己的.Equals覆盖和IComparable实现。当然,这需要您自己以适当的方式处理obj_ -> _组件,这可能会也可能不会。如果您可以控制传递给OtherError构造函数的内容,则应该能够通过将其ErrorMessage向下转换obj为本身在结构上可比较的类型来使该类型工作。但是,这种PrecendenceParserOp情况有点棘手 - 只要您也不需要比较,您就可以在函数组件上使用引用相等来解决问题。

于 2010-02-18T16:49:58.903 回答