seq <obj>与F#</float> </obj>中的seq <float>

时间:2012-08-28 14:56:49

标签: f#

我有以下方法:

  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:\Users\ga1009\Documents\PhD\cpp\pmi\fsharp\pmi\Program.fs 138

如何定义方法addColumnWithHeading以便它也适用于浮点数?

2 个答案:

答案 0 :(得分:4)

内置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

答案 1 :(得分:3)

内联

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>并将字符串转换移到函数外部是另一种选择。