X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=src%2Fhope_result.erl;h=1114197beca3e60d7ac8e5d8f7b2744e25b46b3c;hb=4af0774b16181c76d0deedf0911d53409c8f1078;hp=1b217f845b4fa4c7cfff2a07cc272c9be3e7f762;hpb=8fc25ea1d79ab2c6148b73260490e804bd76ff7c;p=hope.git diff --git a/src/hope_result.erl b/src/hope_result.erl index 1b217f8..1114197 100644 --- a/src/hope_result.erl +++ b/src/hope_result.erl @@ -1,13 +1,17 @@ -module(hope_result). +-behavior(hope_monad). -export_type( [ t/2 ]). -export( - [ pipe/2 + [ return/1 + , map/2 + , pipe/2 , lift_exn/1 + , lift_exn/2 ]). @@ -17,6 +21,18 @@ . +-spec return(A) -> + {ok, A}. +return(X) -> + {ok, X}. + +-spec map(t(A, Error), fun((A) -> (B))) -> + t(B, Error). +map({ok, X}, F) -> + {ok, F(X)}; +map({error, _}=Error, _) -> + Error. + -spec pipe([F], X) -> t(Ok, Error) when X :: any() @@ -24,7 +40,8 @@ , Error :: any() , F :: fun((X) -> t(Ok, Error)) . -pipe([] , X) -> X; +pipe([], X) -> + {ok, X}; pipe([F|Fs], X) -> case F(X) of {error, _}=E -> E @@ -46,3 +63,19 @@ lift_exn(F) when is_function(F, 1) -> {error, {Class, Reason}} end end. + +-spec lift_exn(F, Label) -> G + when F :: fun((A)-> B) + , G :: fun((A)-> t(B, {Label, {Class, Reason :: any()}})) + , Class :: error + | exit + | throw + . +lift_exn(F, Label) when is_function(F, 1) -> + fun(X) -> + try + {ok, F(X)} + catch Class:Reason -> + {error, {Label, {Class, Reason}}} + end + end.