【问题标题】:Tuple.Create in F#在 F# 中创建元组
【发布时间】:2015-01-29 17:09:21
【问题描述】:

我注意到 F# 中 System.Tuple.Create 方法的一个非常奇怪的行为。查看MSDN documentation 时,它表明返回类型为System.Tuple<T>。但是,当在 F# 中使用此方法时,除 Tuple.Create(T) 之外的所有重载都将返回 'T1 * 'T2。显然调用Tuple<T> 构造函数将返回Tuple<T>。但我不明白 Tuple.Create 的返回类型在 F# 中有何不同。

【问题讨论】:

    标签: .net f# tuples base-class-library


    【解决方案1】:

    F#的元组类型(句法元组)编译为System.Tuple<..>。所以它们在 .NET 级别是相同的类型,但对于 F# 类型系统它们是不同的类型:句法元组的类型与 System.Tuple<..> 的类型不匹配,但它们的运行时类型将相同。

    您可以在F# spec找到详细说明

    new System.Tuple<'t>() 的示例没有返回语法元组,可能是因为您显式地实例化了一个特定类型,而您应该准确地返回它。

    这里有一些测试:

    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() 时会得到相同的结果。

    【讨论】:

    • 有趣;虽然语法元组在互操作上与 System.Tuple 兼容,但 F# 拒绝编译 System.Tuple&lt;int, int&gt;(1,1) = (1, 1)我不知道这在实践中会如何导致问题,但这是一个相关点,所以我删除了我的答案以支持这个。
    • @Vandroiy 如果需要,您可以使用 Equals 覆盖:System.Tuple&lt;int, int&gt;(1,1).Equals((1,1))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    相关资源
    最近更新 更多