代码之家  ›  专栏  ›  技术社区  ›  Nathan Shively-Sanders

升级fparsec:升级区分的联合以满足新的相等/比较约束

  •  1
  • Nathan Shively-Sanders  · 技术社区  · 15 年前

    所以,由 hi lar ious series of events ,我下载了fparsec源并尝试构建它。不幸的是,它与新的1.9.9.9不兼容。我解决了一些简单的问题,但仍有一些受到歧视的工会不起作用。

    明确地, Don Syme's post 解释包含类型为的项的有区别的联合 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 tuple,以便可以对du的各个分支进行排序)的正确方法。但这对du的用户来说是不方便的。现在,du的构造需要调用一个函数来获取下一个图章。

    是否有某种方法可以隐藏获取标签,并将相同的构造函数呈现给库的用户?也就是说,在不更改接口的情况下更改实现?这一点尤其重要,因为(根据我对代码的理解)它似乎 PrecedenceParserOp 是公共类型。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Joel Mueller    15 年前

    你为fparsec下载了什么源?我从警察局抓到最新消息 BitBucket repository 我根本不需要对fparsec源代码做任何更改,就可以在vs 2010 rc中编译它。

    编辑:我收回。我确实从interplexyacc和interfparsec示例项目中得到了构建错误,但是核心fparsec和fparsecs项目构建得很好。

        2
  •  1
  •   kvb    15 年前

    你可以做的一件事就是 [<CustomEquality>] [<CustomComparison>] 属性和定义自己的 .Equals 覆盖和 IComparable 实施。当然,这需要你处理 obj _ -> _ 以适当的方式组成自己的组件,这可能是可能的,也可能是不可能的。如果你能控制传递到 OtherError 建设者,你应该能够使这项工作为 ErrorMessage 通过以下方式键入 OBJ 在结构上具有可比性的类型。但是, PrecendenceParserOp case有点棘手——只要不需要进行比较,就可以在函数组件上使用引用相等。