F# 相等/在泛型类型上具有可比性



我有一个这样的记录类型:

type Node<'T> = { doStuff: 'T -> unit ; id: int }

如何实现相等/可比,以便仅等同/比较 id?

注意:这需要在不同类型的节点之间工作。所以等同/比较Node<int>Node<string>.当涉及泛型时,这似乎并不微不足道。

它可以通过一个通用的基本类型来完成:

type IHaveId =
    abstract Id : int
    inherit System.IComparable
type [<CustomEquality; CustomComparison>] Node<'T> =
    { DoStuff: 'T -> unit ; Id: int }
    interface IHaveId with
        member n.Id = n.Id
    override n.Equals n' =
        match n' with
        | :? IHaveId as n' -> n.Id = n'.Id
        | _ -> invalidArg "n'" "Tried to equate incompatible types."
    override n.GetHashCode () = n.Id.GetHashCode()
    interface System.IComparable with
        member n.CompareTo n' =
            match n' with
            | :? IHaveId as n' -> n.Id.CompareTo n'.Id
            | _ -> invalidArg "n'" "Tried to compare incompatible types."

请注意,这不是很快。另外,要小心:随着公共建设访问Node<'T>,可以构建做不同事情但被视为平等的节点。

使用接口进行DoStuff将允许结构比较。如果对象及其 ID 是集中构造的,我会考虑[<ReferenceEquality>]并将比较函数显式传递给需要它的集合(例如 Set<_>Map<_>)。

我猜为该类型编写静态成员将是某种解决方案

static member compareNodes (n1:Node<_>) (n2:Node<_>) =
    n1.id.CompareTo(n2.id)

相关内容

  • 没有找到相关文章

最新更新