可以将类型提供程序作为参数传递给函数

cas*_*bby 7 f# type-providers f#-data

我正在学习F#和FSharp.Data库.我有一个任务,我需要阅读20个CSV文件.每个文件具有不同的列数,但记录具有相同的性质:键入日期字符串,其余所有列都是浮点数.在将结果保存到数据库之前,我需要对float格式数据列进行一些统计计算.虽然我得到了所有的管道逻辑工作:

  • 通过FSharp.Data CSV类型提供程序读取CSV,
  • 使用反射来获取每个列字段的类型以及它们被送入模式匹配的标题名称,这决定了相关的计算逻辑
  • sqlbulkcopy结果),我结束了20个函数(每个CSV文件1个).

解决方案远非可接受.我以为我可以创建一个通用的顶级函数作为循环遍历所有文件的驱动程序.然而,经过几天的尝试,我无处可去.

FSharp.Data CSV类型提供程序具有以下模式:

type Stocks = CsvProvider<"../docs/MSFT.csv">
let msft = Stocks.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")
msft.Data |> Seq.map(fun row -> do something with row)
...
Run Code Online (Sandbox Code Playgroud)

我试过了:

let mainfunc (typefile:string) (datafile:string) =
    let msft = CsvProvider<typefile>.Load(datafile)
    ....
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为CsvProvider抱怨typefile不是有效的常量表达式.我猜测类型提供者必须要求文件在编码时推断出列的类型,在使用相关信息调用mainfunc的代码之前,不能推迟类型推断.

然后我尝试将Type作为参数传递给mainfunc

也不

let mainfunc (typeProvider:CsvProvider<"../docs/MSFT.csv">) =
    ....
Run Code Online (Sandbox Code Playgroud)

也不

let mainfunc<typeProvider:CsvProvider<"../docs/MSFT.csv">> =
    ....
Run Code Online (Sandbox Code Playgroud)

工作.

然后我试图通过MSFT

type Stocks = CsvProvider<"../docs/MSFT.csv">
let msft = Stocks.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")
Run Code Online (Sandbox Code Playgroud)

进入mainFunc.根据intellisence,MSFT有一种类型CsvProvider<...>和MSFT.Data类型seq<CsvProvider<...>>.我试图用这两个显式类型声明一个输入参数,但它们都不能通过编译.

有谁可以请帮助并指出我正确的方向?我在这里错过了一些基本的东西吗?任何.net类型和类对象都可以在F#函数中用于显式指定参数类型,但是我可以对类型提供程序中的类型执行相同的操作吗?

如果上述问题的答案是否定的,那么使逻辑通用处理20个文件甚至200个不同文件的替代方法是什么?

Gus*_*rra 5

这与使用F#TypeProvider类型的Type注释有关,例如FSharp.Data.JsonProvider <...>.DomainTypes.Url

尽管智能感知会显示CsvProvider<...>,引用msft类型,你必须使用类型注释Stocks,并msft.Data代替CsvProvider<...>.Row,你必须使用Stocks.Row.

如果你想做一些动态的东西,你可以得到列的名称,msft.Headers你可以使用这些列的类型Microsoft.FSharp.Reflection.FSharpType.GetTupleElements(typeof<Stocks.Row>)(这是有效的,因为行在运行时被删除为一个元组)

编辑:

如果格式不兼容,并且您正在处理不符合通用格式的动态数据,则可能需要使用CsvFile(http://fsharp.github.io/FSharp.Data/library/CsvFile.html),但你将失去类型提供者的所有类型安全性.您也可以考虑使用Deedle(http://bluemountaincapital.github.io/Deedle/)