2016-02-10 56 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中所述。