-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommon.fs
More file actions
78 lines (52 loc) · 2.25 KB
/
Common.fs
File metadata and controls
78 lines (52 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module FreshBooks2Harvest.Common
open FreshBooks2Harvest.Domain
open System
open System.IO
let first f (a, b) = (f a, b)
let second f (a, b) = (a, f b)
module Result =
let inline (>>=) ma f = Result.bind f ma
let inline (>=>) f g = f >> Result.bind g
let inline (<^>) fab ma = Result.map fab ma
let inline (<*>) mfab ma = Result.bind (fun fab -> fab <^> ma) mfab
let notNull tag a =
match box a with
| null -> Error (tag, Pure "Required value")
| _ -> Ok a
let createDirectory source s =
try
Ok (Directory.CreateDirectory s)
with
| e -> IoError (source, Pure e.Message) |> Error
let readFile source s =
try
Ok (File.ReadAllText s)
with
| e -> IoError (source, Pure e.Message) |> Error
let tag t = Result.mapError (fun e -> (t, e))
let wrapTag f = first f |> Result.mapError
let ofOption error = function Some s -> Ok s | None -> Error error
type ResultBuilder() =
member __.Return(x) = Ok x
member __.ReturnFrom(m: Result<_, _>) = m
member __.Bind(m, f) = Result.bind f m
member __.Bind((m, error): (Option<'T> * 'E), f) = m |> ofOption error |> Result.bind f
member __.Zero() = None
member __.Combine(m, f) = Result.bind f m
member __.Delay(f: unit -> _) = f
member __.Run(f) = f()
member __.TryWith(m, h) =
try __.ReturnFrom(m)
with e -> h e
member __.TryFinally(m, compensation) =
try __.ReturnFrom(m)
finally compensation()
member __.Using(res:#IDisposable, body) =
__.TryFinally(body res, fun () -> match res with null -> () | disp -> disp.Dispose())
member __.While(guard, f) =
if not (guard()) then Ok () else
do f() |> ignore
__.While(guard, f)
member __.For(sequence:seq<_>, body) =
__.Using(sequence.GetEnumerator(), fun enum -> __.While(enum.MoveNext, __.Delay(fun () -> body enum.Current)))
let result = new ResultBuilder()