2016-02-10 34 views
0

我是F#的初学者,我不明白接口是什么以及如何使用接口。 我期待在专家F#中发现的例子3.0第219页F#:接口System.Icomparable

/// 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" 

我试图“复制”这个例子,想创建一个名为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" 

,但它不工作...编译器底层红色覆盖的类型定义抱怨“意外的关键字‘覆盖’。预期的'|'或其他标记“。

PS。我想创建此类型,因为我想使用PriorityQueue类型来提取最大值而不是提取最小值

+1

'type antiint = int'不是键入**定义**,而是键入**缩写**。您只是将新名称给予int类型。下一行以'override'开始并不被编译器识别为任何类型的重写,因为它与语义上不涉及前面的行 – Petr

+0

@petr我看到。所以我该怎么做 ? –

+1

你不能从像int这样的值类型继承。如果您需要创建一个具有自定义行为的数字类型,它需要一些非平凡的工作。请参阅此处的示例:http://tomasp.net/blog/fsharp-custom-numeric.aspx/ – Petr

回答

2

正如已在评论中提到的那样,如果将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属性编写计算或添加运算符,如already referenced blog post I wrote中所述。