2016-07-30 37 views
3

我正在使用CsvTypeProvider将CSV文件中的数据映射到我自己的数据结构中。这工作出色,除了我每次都重复的映射功能:F#CsvTypeProvider - 推断类型的映射函数

type GamesFile = CsvProvider<"./data/15.csv"> 
let games15 = GamesFile.Load("./data/15.csv").Rows |> Seq.map (fun c -> { Division = c.Div; Date = c.Date; HomeScore = c.HomeScore; AwayScore = c.AwayScore }) 
let games16 = GamesFile.Load("./data/16.csv").Rows |> Seq.map (fun c -> { Division = c.Div; Date = c.Date; HomeScore = c.HomeScore; AwayScore = c.AwayScore }) 

当我尝试将其移动到一个功能,据我所知,“根据此前信息不确定类型的对象查找程序点,在这个程序点之前可能需要一个类型注释来约束对象的类型,这可以使查找得到解决。“

这很有道理,但是如何告诉映射函数从CSV的内容推断出类型是什么类型?这通常如何解决?

+1

上'C'只需将鼠标悬停在你的IDE,它会告诉你的类型。它也将清除你对类型定义的困惑。 –

+1

@FyodorSoikin公平地说,类型提供者的tootip有点混乱,因为它忽略了类型别名。 –

回答

5

类型提供程序生成一个代表该行的类型,并将其公开为主提供类型的嵌套类型 - 在您的案例中,其别名为GamesFile

这并不完全是显而易见的,因为编辑器将显示工具提示的东西,如
CsvFile<...>.Row所以它不显示别名的名字,但它表明是嵌套类型。要在代码中使用的类型,你可以只写GamesFile.Row,所以你需要的东西是这样的:

type GamesFile = CsvProvider<"./data/15.csv"> 

let mapRows (rows:seq<GamesFile.Row>) = 
    rows |> Seq.map (fun c -> 
    { Division = c.Div; Date = c.Date; HomeScore = c.HomeScore; AwayScore = c.AwayScore }) 

let games15 = GamesFile.Load("./data/15.csv").Rows |> mapRows 
let games16 = GamesFile.Load("./data/16.csv").Rows |> mapRows 
+1

你也可以写'CsvProvider <“./ data/15.csv”>。行而不是'GamesFile .Row'? –

+0

我相信你可以,但这听起来对我来说不是一个好主意:-) –

+0

尽管如此,这只会让“悬停在”它的解决方案至少可行,即使不是很优雅。 –