F#:接口 System.Icomparable

F#: interface System.Icomparable

我是 F# 的初学者,我不了解什么是接口以及如何使用接口。 我正在查看 Expert F# 3.0 第 219 页中的示例

/// A type abbreviation indicating we're using integers for unique stamps
/// on objects
type stamp = int
/// A structural type containing a function that can't be compared for equality
[<CustomEquality; CustomComparison>]
type MyThing =
{Stamp : stamp;
Behaviour : (int -> int)}
override x.Equals(yobj) =
match yobj with
| :? MyThing as y -> (x.Stamp = y.Stamp)
| _ -> false
override x.GetHashCode() = hash x.Stamp
interface System.IComparable with
member x.CompareTo yobj =
match yobj with
| :? MyThing as y -> compare x.Stamp y.Stamp
| _ -> invalidArg "yobj" "cannot compare values of different types"

我正在尝试 "copy" 这个例子,并想创建一个名为 antiint 的类型,它只是整数,但比较器与正常比较相反。

let anticompare x y = 0 - compare x y

所以我在我的源文件中写了这个:

[<CustomEquality; CustomComparison>]
type antiint = 
     int

     override x.Equals(yobj) =
       match yobj with
         | :? antiint as y -> (x = y)
         | _ -> false
     interface System.IComparable with
       member x.CompareTo yobj =
           match yobj with
             | :? antiint as y -> anticompare x y
             | _ -> invalidArg "yobj" "cannot compare values of different types" 

但它不起作用...编译器底层存在红色覆盖抱怨 "Unexpected keyword 'override' in type definition. Expected '|' or other token"。

PS。我想创建这种类型,因为我想使用 PriorityQueue 类型来提取 max 而不是提取 min

如评论中所述,如果将 antiint 定义为类型缩写(也称为类型别名),则无法覆盖其成员 - 或更改有关类型的任何内容。

最好的方法可能是将其定义为值类型(结构),它是 int 上的薄包装。像这样:

[<Struct; CustomEquality; CustomComparison>]
type antiint(value:int) = 
     member x.Value = value
     override x.Equals(yobj) =
       match yobj with
         | :? antiint as y -> (x = y)
         | _ -> false
     interface System.IComparable with
       member x.CompareTo yobj =
           match yobj with
             | :? antiint as y -> anticompare x y
             | _ -> invalidArg "yobj" "cannot compare values of different types" 

这将被编译为值类型,因此性能开销应该最小。不幸的是,您将无法在上述类型上使用标准数值运算符,因此您可以使用 Value 属性 编写计算或添加 [=14= 中讨论的运算符].