2014-12-01 36 views
4

我注意到在F#的System.Tuple.Create方法的相當怪異的行爲。當查看MSDN documentation時,它表示返回類型爲System.Tuple<T>。但是,在F#中使用此方法時,除Tuple.Create(T)之外的所有過載將返回'T1 * 'T2。顯然調用Tuple<T>構造函數將返回Tuple<T>。但我不明白F#中Tuple.Create的返回類型是如何不同的。Tuple.Create在F#

回答

6

F#(一元組句法)的元組類型被編譯爲System.Tuple<..>。因此,他們是在.NET的水平,但對於F#類型系統中同類型它們是不同的類型:句法元組的類型不會匹配System.Tuple<..>的類型,但是它們的運行時類型將是相同的。

你可以找到與new System.Tuple<'t>()F# spec

的例子詳細說明不返回語法元組,可能是因爲你明確地實例化一個特定的類型,你應當得到這一點。

下面是一些測試:

let x = new System.Tuple<_,_>(2,3) // Creates a Tuple<int,int> 
let y = System.Tuple.Create(2,3) // Creates a syntactic tuple int * int 

let areEqual = x.GetType() = y.GetType() // true 

let f (x:System.Tuple<int,int>) =() 
let g (x:int * int) =() 

let a = f x 
let b = g y 

// but 

let c = f y 
//error FS0001: The type 'int * int' is not compatible with the type 'Tuple<int,int>' 

let d = g x 
// error FS0001: This expression was expected to have type int * int but here has type Tuple<int,int> 

所以,在編譯時它們是不同的,但在運行時它們是相同的。這就是爲什麼當你使用.GetType()時你會得到相同的結果。

+0

有趣;而語法元組是兼容'System.Tuple'上互操作,F#拒絕編譯'System.Tuple (1,1)=(1,1)'。 *我不知道這是如何在實踐中造成的問題,但它是一個相關的問題,所以我刪除我的答案贊成此一* – Vandroiy 2014-12-01 17:18:54

+0

@Vandroiy如果需要,你可以使用的Equals覆蓋:'系統。元組(1,1).Equals((1,1))' – kaefer 2014-12-01 17:21:18