我正在学习 F# 和FSharp.数据库 http://fsharp.github.io/FSharp.Data/。我有一个任务需要读取 20 个 CSV 文件。每个文件都有不同数量的列,但记录具有相同的性质:以日期字符串为键,所有其余列都是浮点数。在将结果保存到数据库之前,我需要对浮点格式数据列进行一些统计计算。尽管我让所有管道逻辑都正常工作:
- 通过 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)
...
我努力了:
let mainfunc (typefile:string) (datafile:string) =
let msft = CsvProvider<typefile>.Load(datafile)
....
这不起作用,因为 CsvProvider 抱怨类型文件不是有效的常量表达式。我猜测类型提供者必须需要该文件来在编码时推断出列的类型,类型推断不能推迟到使用相关信息调用 mainfunc 的代码。
然后我尝试将类型作为参数传递给 mainfunc
neither
let mainfunc (typeProvider:CsvProvider<"../docs/MSFT.csv">) =
....
nor
let mainfunc<typeProvider:CsvProvider<"../docs/MSFT.csv">> =
....
worked.
然后我尝试通过 MSFT
type Stocks = CsvProvider<"../docs/MSFT.csv">
let msft = Stocks.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")
进入 mainFunc。根据情报,MSFT 有一种类型CsvProvider<...>
MSFT.Data 的类型为seq<CsvProvider<...>>
。我试图用这两个显式类型声明一个输入参数,但它们都无法通过编译。
有人可以帮忙并指出我正确的方向吗?我在这里错过了一些基本的东西吗?任何 .net 类型和类对象都可以在 F# 函数中使用来显式指定参数类型,但我可以对类型提供程序中的类型执行相同的操作吗?
如果上述问题的答案是否定的,那么有什么替代方案可以使逻辑通用以处理 20 个文件甚至 200 个不同的文件?