DavidS
DavidS

Reputation: 2283

What is the type returned by "Load" in FSharp Data's CsvProvider

Consider the following code:

  type EnergyInfo = CsvProvider<"Sample.csv">

  let energyInfoBefore = EnergyInfo.Load("File1csv")
  let energyInfoAfter = EnergyInfo.Load("File2.csv")

  let expectedEnergyInfo =
    energyInfoBefore.Rows
      |> Seq.sortBy(fun r -> r.SomeProperty)
      |> Seq.map(fun r ->
        r.Property1,
        r.Property2,
        r.Property3,
        r.Property4,
        r.Property5,
        r.Property6,
        r.Property7)

  let actualEnergyInfo =
    energyInfoAfter.Rows
      |> Seq.sortBy(fun r -> r.SomeProperty)
      |> Seq.map(fun r ->
        r.Property1,
        r.Property2,
        r.Property3,
        r.Property4,
        r.Property5,
        r.Property6,
        r.Property7)  

"expectedInfoBefore" and "expectedInfoAfter" are near identical and naturally I would like to have only one function.

So I thought I'd simply do:

  let getEnergyInfo energyInfo=
    energyInfo.Rows
      |> Seq.sortBy(fun r -> r.SomeProperty)
      |> Seq.map(fun r ->
        r.Property1,
        r.Property2,
        r.Property3,
        r.Property4,
        r.Property5,
        r.Property6,
        r.Property7)

However, at this point my code doesn't compile because the F# compiler is unable to infer the type.

enter image description here

However, I have no idea what type "energyInfo" is. When I hover over the latter, I'm told it's of type "CsvProvider<...>".

As I'm new to both F# and F# data I don't know what I have to do.

Upvotes: 2

Views: 69

Answers (1)

Fyodor Soikin
Fyodor Soikin

Reputation: 80765

The rows returned by your provider are of type EnergyInfo.Row (surprise!), and the whole file is of type EnergyInfo.

The compiler tells you that the type is CsvProvider<"Sample.csv">, because EnergyInfo is a type alias for CsvProvider<"Sample.csv">, and the compiler expands it in the error message. It probably could try to be a bit more helpful, but I'm not sure that's possible in general.

You can let the compiler know the right type by adding a type annotation:

let getEnergyInfo (energyInfo: EnergyInfo) =
    energyInfo.Rows
      |> Seq.sortBy(fun r -> r.SomeProperty)
      |> Seq.map(fun r ->
        r.Property1,
        r.Property2,
        r.Property3,
        r.Property4,
        r.Property5,
        r.Property6,
        r.Property7)

Upvotes: 3

Related Questions