Commit | Line | Data |
---|---|---|
6731749b SK |
1 | -module(hope_result). |
2 | ||
b69220d7 | 3 | -behavior(hope_gen_monad). |
2a40de4f | 4 | |
3b156801 SK |
5 | -export_type( |
6 | [ t/2 | |
7 | ]). | |
6731749b | 8 | |
3b156801 | 9 | -export( |
4af0774b SK |
10 | [ return/1 |
11 | , map/2 | |
a80ca0b2 SK |
12 | , map_error/2 |
13 | , tag_error/2 | |
4af0774b | 14 | , pipe/2 |
8fc25ea1 | 15 | , lift_exn/1 |
b79afea0 | 16 | , lift_exn/2 |
3b156801 | 17 | ]). |
6731749b SK |
18 | |
19 | ||
3b156801 SK |
20 | -type t(A, B) :: |
21 | {ok, A} | |
22 | | {error, B} | |
23 | . | |
6731749b SK |
24 | |
25 | ||
4af0774b SK |
26 | -spec return(A) -> |
27 | {ok, A}. | |
28 | return(X) -> | |
29 | {ok, X}. | |
30 | ||
31 | -spec map(t(A, Error), fun((A) -> (B))) -> | |
32 | t(B, Error). | |
33 | map({ok, X}, F) -> | |
34 | {ok, F(X)}; | |
35 | map({error, _}=Error, _) -> | |
36 | Error. | |
37 | ||
a80ca0b2 SK |
38 | -spec map_error(t(A, B), fun((B) -> (C))) -> |
39 | t(A, C). | |
40 | map_error({ok, _}=Ok, _) -> | |
41 | Ok; | |
42 | map_error({error, Reason}, F) -> | |
43 | {error, F(Reason)}. | |
44 | ||
45 | -spec tag_error(t(A, Reason), Tag) -> | |
46 | t(A, {Tag, Reason}). | |
47 | tag_error({ok, _}=Ok, _) -> | |
48 | Ok; | |
49 | tag_error({error, Reason}, Tag) -> | |
50 | {error, {Tag, Reason}}. | |
51 | ||
ed9905af SK |
52 | -spec pipe([F], X) -> |
53 | t(Ok, Error) | |
54 | when X :: any() | |
55 | , Ok :: any() | |
56 | , Error :: any() | |
57 | , F :: fun((X) -> t(Ok, Error)) | |
58 | . | |
3efbdbc9 SK |
59 | pipe([], X) -> |
60 | {ok, X}; | |
6731749b SK |
61 | pipe([F|Fs], X) -> |
62 | case F(X) | |
63 | of {error, _}=E -> E | |
64 | ; {ok, Y} -> pipe(Fs, Y) | |
65 | end. | |
8fc25ea1 SK |
66 | |
67 | -spec lift_exn(F) -> G | |
68 | when F :: fun((A)-> B) | |
69 | , G :: fun((A)-> t(B, {Class, Reason :: any()})) | |
70 | , Class :: error | |
71 | | exit | |
72 | | throw | |
73 | . | |
74 | lift_exn(F) when is_function(F, 1) -> | |
75 | fun(X) -> | |
76 | try | |
77 | {ok, F(X)} | |
78 | catch Class:Reason -> | |
79 | {error, {Class, Reason}} | |
80 | end | |
81 | end. | |
b79afea0 SK |
82 | |
83 | -spec lift_exn(F, Label) -> G | |
84 | when F :: fun((A)-> B) | |
85 | , G :: fun((A)-> t(B, {Label, {Class, Reason :: any()}})) | |
86 | , Class :: error | |
87 | | exit | |
88 | | throw | |
89 | . | |
90 | lift_exn(F, Label) when is_function(F, 1) -> | |
91 | fun(X) -> | |
92 | try | |
93 | {ok, F(X)} | |
94 | catch Class:Reason -> | |
a80ca0b2 | 95 | tag_error({error, {Class, Reason}}, Label) |
b79afea0 SK |
96 | end |
97 | end. |