Skip to content

Instantly share code, notes, and snippets.

@dmitriid
Created November 19, 2012 16:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitriid/4111451 to your computer and use it in GitHub Desktop.
Save dmitriid/4111451 to your computer and use it in GitHub Desktop.
lift
-spec lift(fun()) -> maybe(_, _).
%% @doc Lift F into maybe().
lift(F) ->
try F() of
ok -> {ok, ok};
{ok, Res} -> {ok, Res};
error -> {error, error};
{error, Rsn} -> {error, Rsn};
Res -> {ok, Res}
catch
throw:{error,Rsn} -> {error, Rsn};
_:{aborted, Rsn} -> exit({aborted, Rsn}); %Mnesia hack
_:Exn -> {error, {lifted_exn, Exn, erlang:get_stacktrace()}}
end.
-spec unlift(fun(() -> broken())) -> _ | no_return().
%% @doc Call F and untag the result. Errors become exceptions.
unlift(F) ->
case F() of
ok -> ok;
{ok, Res} -> Res;
error -> throw({error, error});
{error, Rsn} -> throw({error, Rsn});
Res -> Res
end.
%% @doc XXX this will be renamed
maybe(Thunk, Ok, Error) ->
maybe([Thunk, Error, Ok]).
maybe(CPS) ->
maybe(CPS, []).
maybe([Thunk, Error|Rest], Acc) ->
case lift(Thunk()) of
{error, Rsn} -> Error(Rsn);
{ok, Res} -> maybe(Rest, [Res|Acc])
end;
maybe([Ok], Acc) -> apply(Ok, lists:reverse(Acc)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment