Define and implement a generic monad behavior.
[hope.git] / src / hope_result.erl
CommitLineData
6731749b
SK
1-module(hope_result).
2
4af0774b 3-behavior(hope_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
12 , pipe/2
8fc25ea1 13 , lift_exn/1
b79afea0 14 , lift_exn/2
3b156801 15 ]).
6731749b
SK
16
17
3b156801
SK
18-type t(A, B) ::
19 {ok, A}
20 | {error, B}
21 .
6731749b
SK
22
23
4af0774b
SK
24-spec return(A) ->
25 {ok, A}.
26return(X) ->
27 {ok, X}.
28
29-spec map(t(A, Error), fun((A) -> (B))) ->
30 t(B, Error).
31map({ok, X}, F) ->
32 {ok, F(X)};
33map({error, _}=Error, _) ->
34 Error.
35
ed9905af
SK
36-spec pipe([F], X) ->
37 t(Ok, Error)
38 when X :: any()
39 , Ok :: any()
40 , Error :: any()
41 , F :: fun((X) -> t(Ok, Error))
42 .
3efbdbc9
SK
43pipe([], X) ->
44 {ok, X};
6731749b
SK
45pipe([F|Fs], X) ->
46 case F(X)
47 of {error, _}=E -> E
48 ; {ok, Y} -> pipe(Fs, Y)
49 end.
8fc25ea1
SK
50
51-spec lift_exn(F) -> G
52 when F :: fun((A)-> B)
53 , G :: fun((A)-> t(B, {Class, Reason :: any()}))
54 , Class :: error
55 | exit
56 | throw
57 .
58lift_exn(F) when is_function(F, 1) ->
59 fun(X) ->
60 try
61 {ok, F(X)}
62 catch Class:Reason ->
63 {error, {Class, Reason}}
64 end
65 end.
b79afea0
SK
66
67-spec lift_exn(F, Label) -> G
68 when F :: fun((A)-> B)
69 , G :: fun((A)-> t(B, {Label, {Class, Reason :: any()}}))
70 , Class :: error
71 | exit
72 | throw
73 .
74lift_exn(F, Label) when is_function(F, 1) ->
75 fun(X) ->
76 try
77 {ok, F(X)}
78 catch Class:Reason ->
79 {error, {Label, {Class, Reason}}}
80 end
81 end.
This page took 0.035272 seconds and 4 git commands to generate.