Created
February 22, 2011 17:13
-
-
Save atifaziz/838998 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
type 'a trial = | |
| Succeeded of 'a | |
| Failed of string | |
module Trial = | |
let get = function | |
| Succeeded(v) -> v | |
| Failed(err) -> failwith err | |
let attempt f = | |
try Succeeded(f()) with | e -> Failed(e.GetBaseException().Message) | |
let map f t = | |
match t with | |
| Succeeded(v) -> f v | |
| Failed(_) -> t | |
module Conversion = | |
let date s = DateTime.Parse(s) | |
let int = int | |
let number = float | |
let str s = s | |
module Validate = | |
let ok _ = None | |
let that f b a = if not (f a b) then Some("Invalid") else None | |
let defcol bind map check vs = | |
let i = bind vs | |
(fun vs -> | |
let v = vs |> Seq.nth i | |
let m = Trial.attempt (fun () -> map v) | |
m |> Trial.map (fun v -> match check v with | |
| None -> Succeeded(v) | |
| Some(err) -> Failed(err))) | |
type ColumnReference = | |
| Nth of int | |
| Named of string | |
let defcolr = function | |
| Nth(x) -> | |
defcol (fun _ -> x) | |
| Named(n) -> | |
defcol (Seq.findIndex (fun e -> n.Equals(e, StringComparison.OrdinalIgnoreCase))) | |
let ( *** ) a b record = record |> a, record |> b | |
let detable schema f records = | |
let records = records |> Seq.cache | |
let schema = records |> Seq.head |> schema |> f | |
records |> Seq.skip 1 |> Seq.map schema | |
let schema = (defcolr (Named("DATE" )) Conversion.date (Validate.ok )) | |
*** (defcolr (Nth (1 )) Conversion.int (Validate.that (> ) 0 )) | |
*** (defcolr (Named("PRICE")) Conversion.number (Validate.that (>=) 0.0)) | |
let records = seq { | |
yield ["DATE" ; "HOUR"; "PRICE"] | |
yield ["2010-01-01"; "08" ; "1.234"] | |
yield ["2010-01-01"; "12" ; "2.345"] | |
yield ["2010-01-02"; "08" ; "3.456"] | |
yield ["2010-01-02"; "12" ; "4.567"] | |
yield ["2010-01-03"; "08" ; "5.678"] | |
} | |
records |> detable schema (fun (date, (hour, price)) -> date *** hour *** price) | |
|> Seq.map (fun (date, (hour, price)) -> date, hour, price) | |
|> Seq.iter (printfn "%A") | |
printfn "---------------------" | |
records |> detable schema (fun (date, (hour, price)) -> date *** hour *** price) | |
|> Seq.iter (fun (date, (hour, price)) -> printfn "%A %02d %f" date (hour |> Trial.get) (price |> Trial.get)) | |
printfn "---------------------" | |
records |> detable schema (fun (date, (hour, price)) -> date *** hour *** price) | |
|> Seq.map (fun (date, (hour, price)) -> date, hour |> Trial.get, price |> Trial.get) | |
|> Seq.iter (fun (date, hour, price ) -> printfn "%A %02d %f" date hour price) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment