为什么F#中的CustomEquality和CustomComparison有两种不同的语法?

时间:2017-04-11 08:35:13

标签: f# comparison equality

我想在F#中实现一个类型Symbol,它有一个关联的字符串和位置(比如文本中的行号)。我会这样做:

type Symbol = Symbol of string * int // (string, line number)

我想要一个解除行号的自定义相等。我将有一个“严格相等”,将行号考虑在内,但我希望默认的相等性只比较字符串。看this SO post,似乎必须做如下:

[<CustomEquality; CustomComparison>]
type Symbol =
    | Symbol of string * int
    member x.GetString() =
        match x with
        | Symbol (s, _) -> s
    override x.Equals(y) = // Equality only compares strings, not positions.
        match y with
        | :? Symbol as i -> i.GetString() = x.GetString()
        | _ -> false
     override x.GetHashCode() =
        match x with
        | Symbol (s, p) -> hash (s, p)

但是,要实现自定义比较,必须在上面的声明

下面添加
    interface System.IComparable with
        member x.CompareTo(yobj) = 
            match yobj with
            | :? Symbol as y -> compare (x.GetString()) (y.GetString())
            | _ -> invalidArg "yobj" "cannot compare values of different types"

为什么我可以写override x.Equals(y)...,而不是override x.CompareTo(yobj)...?为什么我必须指定interface System.IComparable with ...?似乎存在System.IEquatable,但我不需要指定它,为什么?这不是一个很大的区别,但我只是想知道为什么差异就在这里。

1 个答案:

答案 0 :(得分:2)

不同之处在于,对于Equals,您将覆盖Object.Equals - 这是基类上的虚方法,而对于CompareTo,您需要实现一个接口(在F#中需要通过&#显式实现) 34;界面..与&#34;。