如何使用命令行参数作为类型提供程序的参数?

时间:2018-08-02 18:56:34

标签: f# type-providers

将动态值用作CsvProvider之类的类型提供程序的参数的正确方法是什么?我希望它能起作用:

open System.IO
open FSharp.Data

[<EntryPoint>]
let main argv =
    type Stock = CsvProvider<argv.[0]>
    let stockData = Stock.Load(argv.[0])

    for row in stockData.Rows do
        printfn "(%A, %A, %A, %A)" row.High row.Low row.Open row.Close

    0 //Exit

我在做什么错了?

2 个答案:

答案 0 :(得分:3)

您不能将命令行参数用作类型提供程序的静态参数。第type Stock = CsvProvider<argv.[0]>行要求CsvProvider的参数为编译时常量,因为类型提供程序生成的类型是在编译时而不是在运行时创建的。

您可以为Load函数提供一个不同的值,并且它可以是一个运行时值,就像在行Stock.Load(argv.[0])中一样,但是您将需要使用编译时常量文件名称或示例数据,它们与作为命令行参数传递的文件的预期布局相匹配,因此在编译时生成的类型将与在运行时传递的文件的结构相匹配(即使数据可能会有所不同。)

答案 1 :(得分:0)

对于任何类型的提供程序,您都需要一个架构,以便编译器可以理解数据的外观。因此,它必须是在编译时可用的东西。一种方法是将其放入文件中:

High,Low,Open,Close
29.53,29.17,29.45,29.23
29.70,29.40,29.61,29.50
29.65,29.07,29.07,29.56
29.57,29.18,29.47,29.34

然后您可以像这样导入main函数的外部

// or whatever you called the file
type Stock = CsvProvider<"schema.csv">

如果您愿意,CsvProvider还可让您直接给它内联架构:

type Stock = CsvProvider<"High,Low,Open,Close
                          29.53,29.17,29.45,29.23">

在这里是整个程序的上下文:

open System.IO
open FSharp.Data

type Stock = CsvProvider<"schema.csv">


[<EntryPoint>]
let main argv =
    let stockData = Stock.Load(argv.[0])

    for row in stockData.Rows do
        printfn "(%A, %A, %A, %A)" row.High row.Low row.Open row.Close

    0