F# type providers are awesome

For example, consider the csv format, that is quite common in business interfaces.

Well, F# provider has all the options you may need to load it.

type PL = 
        Sample = sample,
        Separators = ";", SkipRows = 1, HasHeaders = false, 
        Schema ="CargoID(string),CurrencyType(string),Currency(string),Amount(decimal)">

Now, we borrow a function from Reed Copsey

let tryToInt s = 
    match System.Int32.TryParse s with
    | true, v -> Some v
    | false, _ -> None

and then we can invent a cool, original, functional way to choose only the lines with a parsable int in the field for cargo id. We are indeed unleashing the power of F# Type Providers when we pass the safe-typed row in the signature of the following.

let withCargoID (rows:PL.Row[]) =
    |> Array.choose(fun r -> 
        tryToInt r.CargoID
        |> Option.bind (fun _ -> Some r)

and the rest is an easy exercise of grouping

type CurrencyGroup = {CurrencyType: string; Currency: string}

let parse (filename:string) = 
    let pl = PL.Load filename
    let rows = pl.Rows |> Seq.toArray
    let header = rows |> Array.head
    printfn "rows #: %d with cargoes %d" rows.Length (withCargoID rows).Length
    printfn "first line => CargoID: %s, CurrencyType: %s, Currency: %s, Amount: %f!" header.CargoID header.CurrencyType header.Currency header.Amount
    let currGroups = 
        |> Array.groupBy( fun r ->
            {Currency = r.Currency; CurrencyType = r.CurrencyType}
    |> Array.iter( fun (g, r) ->
        printfn "Currency %s CurrencyType %s #: %d with cargoes: %d" g.Currency g.CurrencyType r.Length (withCargoID r).Length
    |> Array.sumBy(fun (g, r) -> r.Length)
    |> printfn "total records in all currencies %d" 
    |> Array.sumBy(fun (g, r) -> (withCargoID r).Length)
    |> printfn "total with cargoes in all currencies %d" 
    printfn "parsed fine!"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s