简体   繁体   中英

Tuple.Create in F#

I noticed a quite weird behavior of the System.Tuple.Create method in F#. When looking at the MSDN documentation it indicates that the return type is of System.Tuple<T> . However when using this method in F# all overloads except Tuple.Create(T) will return 'T1 * 'T2 . Obviously invoking the Tuple<T> constructor will return Tuple<T> . But I don't understand how the return type of the Tuple.Create is different in F#.

The tuple type of F# (a syntactic tuple) is compiled as System.Tuple<..> . So they are the same type at .NET level but for F# type system they are different types: the type of a syntactic tuple will not match the type of a System.Tuple<..> but their runtime type will be the same.

You can find a detailed description in the F# spec

The example with new System.Tuple<'t>() does not return a syntactic tuple, probably because you are instantiating explicitly a specific type and you should get back exactly that.

Here are some tests:

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>  

So, at compile time they are different but at runtime they are the same. That's why when you use .GetType() you get the same result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM