F#:interface System.Icomparable

时间:2016-02-10 13:37:18

标签: types interface f# override icomparable

我是F#的初学者,我不明白使用界面是什么以及如何使用界面。 我正在查看专家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"

我试图&#34;复制&#34;这个例子并且想要创建一个名为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" 

但它不起作用...编译器是红色覆盖投诉的基础&#34;意外的关键字&#39;覆盖&#39;在类型定义中。期待&#39; |&#39;或其他标记&#34;。

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

1 个答案:

答案 0 :(得分:2)

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

最好的方法可能是将它定义为值类型(struct),它是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属性编写计算或添加运算符,如already referenced blog post I wrote中所述。