2016-07-30 63 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

儘管如此,這隻會讓「懸停在」它的解決方案至少可行,即使不是很優雅。 –