简体   繁体   中英

seq<obj> versus seq<float> in F#

I have the following method:

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

which takes a string heading and any sequence (which is compiled to seq in this case), creates a sequence of strings and calls another method with this data. However, it doesn't work with column being a sequence of floats:

Error   1   The type 'obj' does not match the type 'float'  C:\Users\ga1009\Documents\PhD\cpp\pmi\fsharp\pmi\Program.fs 138

How can I define the method addColumnWithHeading so that it works with floats as well?

The built-in string function is an inline function which uses a statically-resolved generic parameter; since your addColumnWithHeading method is not declared inline , the F# type inference has to assume the values in the sequence are of type obj .

There's a simple solution though -- swap out the string function in favor of "manually" calling .ToString() on the values in the sequence. If you do that, F# will be able to use a standard generic parameter type for the sequence so you can pass a sequence of any type you desire.

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

string is inlined so its argument type has to be resolved at compile-time. Since your member is not inlined it picks the most general type it can ( obj in this case). Inlining your method will allow column to remain generic.

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

EDIT

Per the comments to Jack's answer, you might not need to inline your use of string . Certainly, if column will always be seq<float> you should just add a type annotation. Passing seq<string> and moving the string conversion outside the function is another option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM