Skip to content

Instantly share code, notes, and snippets.

@maximvl
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximvl/380e2f7709406aea3b09 to your computer and use it in GitHub Desktop.
Save maximvl/380e2f7709406aea3b09 to your computer and use it in GitHub Desktop.
~/dev/erl $ erl -pa .
Eshell V6.3 (abort with ^G)
1> maybe:start_link().
{ok,<0.34.0>}
2> maybe:unlift(5).
{error,badarg}
3> N = maybe:nothing().
#Ref<0.0.0.32>
4> maybe:unlift(N).
nothing
5> V = maybe:just(5).
#Ref<0.0.0.53>
6> maybe:unlift(V).
{just,5}
7>
-module(maybe).
-behaviour(gen_server).
%% API
-export([start_link/0, just/1, nothing/0, unlift/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {storage=ets:new(storage, []), nothing=make_ref()}).
%%%===================================================================
%%% API
%%%===================================================================
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
just(Val) ->
gen_server:call(?SERVER, {just, Val}).
nothing() ->
gen_server:call(?SERVER, nothing).
unlift(Id) ->
gen_server:call(?SERVER, {get, Id}).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
init([]) ->
{ok, #state{}}.
handle_call({just, Value}, _From, State) ->
Id = make_ref(),
ets:insert(State#state.storage, {Id, Value}),
{reply, Id, State};
handle_call(nothing, _From, State) ->
{reply, State#state.nothing, State};
handle_call({get, Id}, _From, #state{nothing=Id}=State) ->
{reply, nothing, State};
handle_call({get, Id}, _From, State) ->
case ets:lookup(State#state.storage, Id) of
[{Id, Value}] ->
{reply, {just, Value}, State};
_ ->
{reply, {error, badarg}, State}
end.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment