Implement hope_result:(map_error and tag_error)
[hope.git] / src / hope_result.erl
CommitLineData
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}.
28return(X) ->
29 {ok, X}.
30
31-spec map(t(A, Error), fun((A) -> (B))) ->
32 t(B, Error).
33map({ok, X}, F) ->
34 {ok, F(X)};
35map({error, _}=Error, _) ->
36 Error.
37
a80ca0b2
SK
38-spec map_error(t(A, B), fun((B) -> (C))) ->
39 t(A, C).
40map_error({ok, _}=Ok, _) ->
41 Ok;
42map_error({error, Reason}, F) ->
43 {error, F(Reason)}.
44
45-spec tag_error(t(A, Reason), Tag) ->
46 t(A, {Tag, Reason}).
47tag_error({ok, _}=Ok, _) ->
48 Ok;
49tag_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
59pipe([], X) ->
60 {ok, X};
6731749b
SK
61pipe([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 .
74lift_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 .
90lift_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.
This page took 0.035164 seconds and 4 git commands to generate.