F# - >为HashSet实现IComparable<'a>

时间:2011-04-05 20:13:22

标签: f#

是否有可能以某种方式为IComparable实施HashSet<'a>?这样做的原因是我声明了以下记录:

[<StructuralComparison>]
type Category = { 
    mutable Id: string; 
    Name: string; 
    SavePath: string;
    Tags: HashSet<Tag> }

and Tag = { Tag:string; }

如您所见,Category记录中的标记属于HashSet<Tag>类型 - 为了将一系列类别映射到地图,我需要实现{{1不知何故......否则它只会导致:

  

结构,记录或联合类型   '类别'有   'StructuralComparison'属性但是   组件类型'HashSet'可以   不满足'比较'

请注意,除了IComparable之外,我无法使用任何其他内容,因为我正在使用的数据库可以理解任何fsharp-ish列表。

2 个答案:

答案 0 :(得分:13)

我假设您想要仅考虑CategoryIdName(按此顺序)来比较和等同SavePath,记录表现为Tags不存在:

open System
open System.Collections.Generic

[<CustomComparison; CustomEquality>]
type Category =
    { mutable Id : string;
      Name       : string;
      SavePath   : string;
      Tags       : HashSet<Tag> }
    interface IComparable<Category> with
        member this.CompareTo { Id = id; Name = name; SavePath = savePath } =
            compare (this.Id, this.Name, this.SavePath) (id, name, savePath)
    interface IComparable with
        member this.CompareTo obj =
            match obj with
              | null                 -> 1
              | :? Category as other -> (this :> IComparable<_>).CompareTo other
              | _                    -> invalidArg "obj" "not a Category"
    interface IEquatable<Category> with
        member this.Equals { Id = id; Name = name; SavePath = savePath } =
            this.Id = id && this.Name = name && this.SavePath = savePath
    override this.Equals obj =
        match obj with
          | :? Category as other -> (this :> IEquatable<_>).Equals other
          | _                    -> false
    override this.GetHashCode () =
        hash (this.Id, this.Name, this.SavePath)

and Tag = { Tag : string; }

但是,如果您希望按Name进行比较并等同Id,请考虑以下事项:

open System
open System.Collections.Generic

[<CustomComparison; CustomEquality>]
type Category =
    { mutable Id : string;
      Name       : string;
      SavePath   : string;
      Tags       : HashSet<Tag> }
    interface IComparable<Category> with
        member this.CompareTo { Name = name } =
            this.Name.CompareTo name
    interface IComparable with
        member this.CompareTo obj =
            match obj with
              | null                 -> 1
              | :? Category as other -> (this :> IComparable<_>).CompareTo other
              | _                    -> invalidArg "obj" "not a Category"
    interface IEquatable<Category> with
        member this.Equals { Id = id } =
            this.Id = id
    override this.Equals obj =
        match obj with
          | :? Category as other -> (this :> IEquatable<_>).Equals other
          | _                    -> false
    override this.GetHashCode () =
        this.Id.GetHashCode ()

and Tag = { Tag : string; }

答案 1 :(得分:2)

http://blogs.msdn.com/b/dsyme/archive/2009/11/08/equality-and-comparison-constraints-in-f-1-9-7.aspx

简单地说,我认为您希望将CustomEqualityCustomComparison属性应用于此类型,然后自行实现。