Skip to content

Instantly share code, notes, and snippets.

@yodiz
Last active July 2, 2020 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yodiz/8c5e7ef9c1de4cc56921e76c561179b8 to your computer and use it in GitHub Desktop.
Save yodiz/8c5e7ef9c1de4cc56921e76c561179b8 to your computer and use it in GitHub Desktop.
type Transaction<'a> = string -> 'a
module Transaction =
let map<'a,'b> (mapper:'a -> 'b) (t:Transaction<'a>) : Transaction<'b> =
(fun x -> mapper (t x))
let bind<'a,'b> (binder:'a -> Transaction<'b>) (t:Transaction<'a>) : Transaction<'b> =
(fun x -> binder (t x) x)
let execute connectionString (t:Transaction<'a>) =
t ConnectionString
type SqlReader<'state, 'element> =
abstract member Read : reader:('state -> System.Data.IDataReader -> 'element -> 'state*bool) -> 'state -> Transaction<'state>
module SqlReader =
let read<'state,'element> reader state (x:SqlReader<'state, 'element>) = x.Read reader state
let fold<'state, 'element> folder = read<'state, 'element> (fun s _r x -> (folder s x), true)
let readList<'a> = fold<_ list, 'a> (fun s x -> x::s) [] >> Transaction.map List.rev
let optional<'a> = read<_ option, 'a> (fun s _r x -> (Some x), false) None
let single<'a> = optional<'a> >> Transaction.map (Option.defaultWith (fun () -> failwithf "Expected one row, got zero"))
let genericList<'a> = new System.Collections.Generic.List<'a>() |> fold<_, 'a> (fun s x -> s.Add(x); s)
let a : int =
SqlReaderProvider<"SELECT @n AS N">.Query(5)
|> SqlReader.single
|> Transaction.execute
()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment