Reputation: 2487
I'm reading about F# and trying to apply it to my daily job.
I was already been able to load a CSV file with the help of FSharp.Data
from NuGet, but I did it a imperative style, I think. Now I'm trying to apply functional constructs, tried the following:
open System
open System.IO
open FSharp.Data
[<EntryPoint>]
let main argv =
let data =
argv.[0]
|> Path.Combine Environment.CurrentDirectory
|> CsvFile.Load
printfn "%A" data.Headers
0
What I'm missing here?
In my head argv.[0]
is passed to the result of Path.Combine Environment.CurrentDirectory
which curried already have the current dir as the first path
then the combined result is given to CsvFile.Load
.
Did I get |>
and curring wrong?
Upvotes: 1
Views: 105
Reputation: 6510
Because Path.Combine
is a C# function which takes a params
array, you cannot pipe parameters into the non-zero positions. You can create an array and pass that instead:
[|Environment.CurrentDirectory; argv.[0]|]
|> Path.Combine
|> CsvFile.Load
Upvotes: 3
Reputation: 36718
Your pipeline looks correct, so I suspect that your issue is that CsvFile.Load
is documented to take a URI, not a filename. To check whether you're getting the right filename, I would first replace CsvFile.Load
with printfn "Got result: %s"
in your pipeline to check whether you're getting the filename you expect. Then if it is what you expect (and I think it will be), you can add another step to the pipeline:
[<EntryPoint>]
let main argv =
let data =
argv.[0]
|> Path.Combine Environment.CurrentDirectory
|> sprintf "file://%s" // Convert filename to URI
|> CsvFile.Load
printfn "%A" data.Headers
0
Since you're apparently new to F#, I'll expand those steps a little so you can confirm that your intuition is correct:
argv.[0]
|> Path.Combine Environment.CurrentDirectory
This is like calling Path.Combine Environment.CurrentDirectory argv.[0]
.
argv.[0]
|> Path.Combine Environment.CurrentDirectory
|> sprintf "file://%s" // Convert filename to URI
This is like calling sprintf "file://%s" (Path.Combine Environment.CurrentDirectory argv.[0])
.
argv.[0]
|> Path.Combine Environment.CurrentDirectory
|> sprintf "file://%s" // Convert filename to URI
|> CsvFile.Load
This is like calling CsvFile.Load (sprintf "file://%s" (Path.Combine Environment.CurrentDirectory argv.[0]))
.
From what you said in your question, it looks like this agrees with your understanding because you're understanding pipes correctly. So just pass CsvFile.Load
a URI instead of a filename and you should be fine.
Upvotes: 1