F#:IEnumerable <tuple <ta,tb>&gt;与list <ta * tb>不兼容?</ta * tb> </tuple <ta,tb>

时间:2014-03-21 18:43:12

标签: generics f# tuples

所以我有以下代码,它给出了类型不匹配编译器错误,我不知道为什么:

[<Test>]
member this.TheTest() =
    let tuple = (DateTime.Now, 10)
    let listOfTuples = [ tuple ]
    SomeType.SomeFunc(listOfTuples)

static member SomeFunc (listOfTuples: IEnumerable<Tuple<DateTime,int>>) =
    Console.WriteLine("foo")

为什么类型不兼容?

更重要的是,如何表达SomeFunc的签名与电话兼容?

1 个答案:

答案 0 :(得分:4)

这里的实际问题是尝试将('a * 'b)传递给一个接受Tuple<'a, 'b>的函数。虽然这些内部表示是相同的,但F#编译器对这两者的处理方式不同。

这是在F# language spec, section 6.3.2

中详细说明的
  

当被视为静态类型时,元组类型与其编码形式不同。但是,元组值和类型的编码形式在F#类型系统中通过运行时类型可见。

问题是编译器使用“静态类型”来查看此函数是否匹配,并且根据规范,它不是。

  

更重要的是,如何表达SomeFunc的签名以与呼叫兼容?

您可以通过各种方式解决此问题。最简单的方法是重新定义方法的类型规范以使用元组表达式:

static member SomeFunc (listOfTuples: IEnumerable<(DateTime * int)>) =
    Console.WriteLine("foo")

请注意,上述内容可以用更恰当的方式(具有完全相同的含义)写成:

static member SomeFunc (listOfTuples: (DateTime * int) seq) =
    Console.WriteLine("foo")