3 -behavior(hope_gen_monad).
12 % Generic monad interface
14 , map/2 % map/2 is alias for map_ok/2
17 % Specific to hope_result:t()
46 -spec map(t(A, Error), fun((A) -> (B))) ->
51 -spec map_ok(t(A, Error), fun((A) -> (B))) ->
55 map_ok({error, _}=Error, _) ->
58 -spec map_error(t(A, B), fun((B) -> (C))) ->
60 map_error({ok, _}=Ok, _) ->
62 map_error({error, Reason}, F) ->
65 -spec tag_error(t(A, Reason), Tag) ->
67 tag_error({ok, _}=Ok, _) ->
69 tag_error({error, Reason}, Tag) ->
70 {error, {Tag, Reason}}.
77 , F :: fun((X) -> t(Ok, Error))
84 ; {ok, Y} -> pipe(Fs, Y)
87 -spec lift_exn(F) -> G
88 when F :: fun((A) -> B)
89 , G :: fun((A) -> t(B, exn_value(any())))
91 lift_exn(F) when is_function(F, 1) ->
92 ID = fun hope_fun:id/1,
93 lift_map_exn(F, ID, ID).
95 -spec lift_exn(F, ErrorTag) -> G
96 when F :: fun((A) -> B)
97 , G :: fun((A) -> t(B, {ErrorTag, exn_value(any())}))
99 lift_exn(F, ErrorTag) when is_function(F, 1) ->
100 ID = fun hope_fun:id/1,
101 Tag = fun (Reason) -> {ErrorTag, Reason} end,
102 lift_map_exn(F, ID, Tag).
104 -spec lift_map_exn(F, MapOk, MapError) -> G
105 when F :: fun((A) -> B)
106 , MapOk :: fun((B) -> C)
107 , MapError :: fun((exn_value(any())) -> Error)
108 , G :: fun((A) -> t(C, Error))
110 lift_map_exn(F, MapOk, MapError) when is_function(F, 1) ->
115 catch Class:Reason ->
116 {error, {Class, Reason}}
118 % Applying maps separately as to not unintentionally catch an exception
121 of {ok , _}=Ok -> map_ok (Ok , MapOk)
122 ; {error, _}=Error -> map_error(Error, MapError)