%% @author alexeikrasnopolski %% @doc @todo Add description to monad_test. -module(monad_test). -include_lib("eunit/include/eunit.hrl"). %% ==================================================================== %% API functions %% ==================================================================== -export([continuation/1]). %bind(nothing, _C) -> nothing; %bind(F, C) -> C(F). %bind(F, C) -> fun(nothing) -> nothing; (A) -> C(F(A)) end. bind({error, State}, _) -> {error, State}; bind(F, C) -> fun ({error, State}) -> {error, State}; ({_Status, State}) -> C(F(State)) end. return() -> fun(X) -> X end. %% continuation([f1, f2, f3]) -> %% bind(f1, %% bind(f2, %% bind(f3, %% return) %% ) %% ) %% . return() == fun() -> f3(2)(S) continuation([]) -> return(); continuation([F | RF]) -> bind(F, continuation(RF)) . f_test() -> Cont = continuation([add(5),sub(3),mult(2)]), io:format(user, "Result = ~p~n~n", [Cont({2,0})]), io:format(user, "Result = ~p~n~n", [Cont({-6,0})]), Cont1 = continuation([add(5),sub(-3),mult(2)]), io:format(user, "Result = ~p~n~n", [Cont1({2,0})]), Cont2 = continuation([add(5),sub(3),mult(0)]), io:format(user, "Result = ~p~n~n", [Cont2({2,0})]) %% io:format(user, "Result = ~p~n~n", [Cont(3)]) . %% ==================================================================== %% Internal functions %% ==================================================================== add(A) -> fun(State) -> io:format(user, "add >>> Status:~p State:~p~n", [A, State]), case A of A when A < 0 -> {error, State}; _ -> {ok, State + A} end end. sub(A) -> fun(State) -> io:format(user, "sub >>> Status:~p State:~p~n", [A, State]), case A of A when A < 0 -> {error, State}; _ -> {ok, State - A} end end. mult(A) -> fun(State) -> io:format(user, "mult >>> Status:~p State:~p~n", [A, State]), case A of A when A == 0 -> {error, State}; _ -> {ok, State * A} end end.