<obj> <float> F# 中的 seq 与 seq 的比较



我有以下方法:

  member this.addColumnWithHeading heading column =
    this.addColumn (seq { yield heading; yield! (column |> Seq.map string)})

它采用一个字符串标题和任何序列(在本例中编译为seq),创建一个字符串序列并用该数据调用另一个方法。然而,它不适用于列是一个浮动序列的情况:

Error   1   The type 'obj' does not match the type 'float'  C:Usersga1009DocumentsPhDcpppmifsharppmiProgram.fs 138

如何定义方法addColumnWithHeading,使其也能使用浮点运算?

内置的string函数是一个内联函数,它使用静态解析的泛型参数;由于您的addColumnWithHeading方法未声明为inline,F#类型推断必须假定序列中的值为obj类型。

不过,有一个简单的解决方案——换掉string函数,对序列中的值"手动"调用.ToString()。如果你这样做,F#将能够为序列使用标准的泛型参数类型,这样你就可以传递你想要的任何类型的序列。

member this.addColumnWithHeading heading column =
    seq {
        yield heading
        yield! Seq.map (fun x -> x.ToString()) column }
    |> this.addColumn

string是内联的,因此必须在编译时解析其参数类型。由于您的成员不是内联的,所以它会选择最通用的类型(在本例中为obj)。嵌入您的方法将允许column保持通用性。

member inline x.AddColumnWithHeading(heading, column) =
  x.AddColumn(seq { yield heading; yield! Seq.map string column })

编辑

根据Jack的回答,您可能不需要内联string的使用。当然,如果column总是seq<float>,那么您应该添加一个类型注释。传递seq<string>并将字符串转换移到函数之外是另一种选择。

最新更新