【问题标题】:F#: IEnumerable<Tuple<TA,TB>> is not compatible with list<TA*TB>?F#: IEnumerable<Tuple<TA,TB>> 与 list<TA*TB> 不兼容?
【发布时间】:2014-03-21 18:43:11
【问题描述】:

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

[<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的签名以兼容调用?

【问题讨论】:

  • 这基本上是同一个问题:stackoverflow.com/q/21870026/65358只是System.Tuple和元组表达式不匹配
  • 不完全一样,因为该问题中的答案是关于元组中元素的数量,但是在我的问题中,我只是在询问 2 的特定长度
  • @ReedCopsey:更新问题,表达它的最终目的(与重复不匹配)
  • 你试过seq&lt;DateTime * int&gt;而不是IEnumerable&lt;Tuple&lt;DateTime,int&gt;&gt;吗?
  • 请注意,将IEnumerable 替换为seq 不是必需的(它们实际上是等效的),只是因为它更短更方便。必要的部分是将Tuple&lt;a,b&gt; 替换为a * b

标签: generics f# tuples


【解决方案1】:

这里的实际问题是试图将('a * 'b) 传递给采用Tuple&lt;'a, 'b&gt; 的函数。虽然它们的内部表示相同,但​​ 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")

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2020-06-14
    • 2017-03-09
    • 2021-07-29
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多