Current section
Files
Jump to
Current section
Files
src/decepticon@stateful.erl
-module(decepticon@stateful).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([action/1, get/0, put/1, map/2, apply/2, do/2, run/2, eval/2, exec/2, increment_state/0]).
-export_type([state/2]).
-type state(FJS, FJT) :: {state, fun((FJT) -> {FJS, FJT})}.
-spec action(FJU) -> state(FJU, any()).
action(Action_value) ->
{state, fun(S) -> {Action_value, S} end}.
-spec get() -> state(FJY, FJY).
get() ->
{state, fun(S) -> {S, S} end}.
-spec put(FKB) -> state(nil, FKB).
put(State_value) ->
{state, fun(_) -> {nil, State_value} end}.
-spec map(state(FKE, FKF), fun((FKE) -> FKI)) -> state(FKI, FKF).
map(State, Map_fn) ->
{state,
fun(S) ->
{A, S@1} = (erlang:element(2, State))(S),
{Map_fn(A), S@1}
end}.
-spec apply(state(fun((FKL) -> FKM), FKN), state(FKL, FKN)) -> state(FKM, FKN).
apply(Prev, Next) ->
{state,
fun(S) ->
{F, S@1} = (erlang:element(2, Prev))(S),
{A, S@2} = (erlang:element(2, Next))(S@1),
{F(A), S@2}
end}.
-spec do(state(FKU, FKV), fun((FKU) -> state(FKY, FKV))) -> state(FKY, FKV).
do(State, And_then_fn) ->
{state,
fun(S) ->
{A, S@1} = (erlang:element(2, State))(S),
(erlang:element(2, And_then_fn(A)))(S@1)
end}.
-spec run(state(FLD, FLE), FLE) -> {FLD, FLE}.
run(State, Initial) ->
(erlang:element(2, State))(Initial).
-spec eval(state(FLH, FLI), FLI) -> FLH.
eval(State, Initial) ->
{A, _} = run(State, Initial),
A.
-spec exec(state(any(), FLM), FLM) -> FLM.
exec(State, Initial) ->
{_, S} = run(State, Initial),
S.
-spec increment_state() -> state(nil, integer()).
increment_state() ->
{state, fun(S) -> {nil, S + 1} end}.