-module(act). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([run/2, eval/2, exec/2, return/1, ok/1, error/1, get_state/0, set_state/1, update_state/1, map/2, map_ok/2, map_error/2, do/2, 'try'/2, all/1, each/1, try_all/1, try_each/1, flatten/1]). -spec run(fun((FKC) -> {FKC, FKB}), FKC) -> {FKC, FKB}. run(Action, State) -> Action(State). -spec eval(fun((FKG) -> {FKG, FKF}), FKG) -> FKF. eval(Action, State) -> erlang:element(2, Action(State)). -spec exec(fun((FKK) -> {FKK, any()}), FKK) -> FKK. exec(Action, State) -> erlang:element(1, Action(State)). -spec return(FKN) -> fun((FKO) -> {FKO, FKN}). return(Result) -> fun(State) -> {State, Result} end. -spec ok(FKR) -> fun((FKT) -> {FKT, {ok, FKR} | {error, any()}}). ok(Value) -> fun(State) -> {State, {ok, Value}} end. -spec error(FKX) -> fun((FKZ) -> {FKZ, {ok, any()} | {error, FKX}}). error(Value) -> fun(State) -> {State, {error, Value}} end. -spec get_state() -> fun((FLD) -> {FLD, FLD}). get_state() -> fun(State) -> {State, State} end. -spec set_state(FLG) -> fun((FLG) -> {FLG, nil}). set_state(State) -> fun(_) -> {State, nil} end. -spec update_state(fun((FLJ) -> FLJ)) -> fun((FLJ) -> {FLJ, nil}). update_state(Updater) -> fun(State) -> {Updater(State), nil} end. -spec map(fun((FLN) -> {FLN, FLM}), fun((FLM) -> FLQ)) -> fun((FLN) -> {FLN, FLQ}). map(Action, F) -> fun(State) -> {State@1, Result} = Action(State), {State@1, F(Result)} end. -spec map_ok(fun((FLV) -> {FLV, {ok, FLT} | {error, FLU}}), fun((FLT) -> FLZ)) -> fun((FLV) -> {FLV, {ok, FLZ} | {error, FLU}}). map_ok(Action, F) -> fun(State) -> {State@1, Result} = Action(State), case Result of {ok, A} -> {State@1, {ok, F(A)}}; {error, E} -> {State@1, {error, E}} end end. -spec map_error( fun((FMF) -> {FMF, {ok, FMD} | {error, FME}}), fun((FME) -> FMJ) ) -> fun((FMF) -> {FMF, {ok, FMD} | {error, FMJ}}). map_error(Action, F) -> fun(State) -> {State@1, Result} = Action(State), case Result of {error, E} -> {State@1, {error, F(E)}}; {ok, A} -> {State@1, {ok, A}} end end. -spec do(fun((FMO) -> {FMO, FMN}), fun((FMN) -> fun((FMO) -> {FMO, FMR}))) -> fun((FMO) -> {FMO, FMR}). do(First_do, And_then) -> fun(State) -> {State@1, Result} = First_do(State), (And_then(Result))(State@1) end. -spec 'try'( fun((FMY) -> {FMY, {ok, FMW} | {error, FMX}}), fun((FMW) -> fun((FMY) -> {FMY, {ok, FNC} | {error, FMX}})) ) -> fun((FMY) -> {FMY, {ok, FNC} | {error, FMX}}). 'try'(First_try, And_then) -> fun(State) -> {State@1, Result} = First_try(State), case Result of {ok, A} -> (And_then(A))(State@1); {error, E} -> {State@1, {error, E}} end end. -spec all(list(fun((FNK) -> {FNK, FNJ}))) -> fun((FNK) -> {FNK, list(FNJ)}). all(Actions) -> fun(_capture) -> gleam@list:map_fold( Actions, _capture, fun(State, Action) -> Action(State) end ) end. -spec each(list(fun((FNS) -> {FNS, any()}))) -> fun((FNS) -> {FNS, nil}). each(Actions) -> fun(State) -> {gleam@list:fold( Actions, State, fun(State@1, Action) -> erlang:element(1, Action(State@1)) end ), nil} end. -spec try_all(list(fun((FOA) -> {FOA, {ok, FNY} | {error, FNZ}}))) -> fun((FOA) -> {FOA, {ok, list(FNY)} | {error, FNZ}}). try_all(Actions) -> _pipe = fun(State) -> gleam@list:fold_until( Actions, {State, {ok, []}}, fun(Acc, Action) -> {State@1, {ok, Results}} = case Acc of {_, {ok, _}} -> Acc; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"act"/utf8>>, function => <<"try_all"/utf8>>, line => 283}) end, case Action(State@1) of {New_state, {ok, Result}} -> {continue, {New_state, {ok, [Result | Results]}}}; {New_state@1, {error, Result@1}} -> {stop, {New_state@1, {error, Result@1}}} end end ) end, map_ok(_pipe, fun gleam@list:reverse/1). -spec try_each(list(fun((FOL) -> {FOL, {ok, any()} | {error, FOK}}))) -> fun((FOL) -> {FOL, {ok, nil} | {error, FOK}}). try_each(Actions) -> fun(State) -> gleam@list:fold_until( Actions, {State, {ok, nil}}, fun(Acc, Action) -> {State@1, Nil_result} = Acc, case Action(State@1) of {New_state, {ok, _}} -> {continue, {New_state, Nil_result}}; {New_state@1, {error, Result}} -> {stop, {New_state@1, {error, Result}}} end end ) end. -spec flatten(fun((FOU) -> {FOU, fun((FOU) -> {FOU, FOT})})) -> fun((FOU) -> {FOU, FOT}). flatten(Action) -> fun(State) -> {State@1, Action@1} = Action(State), {State@2, Result} = Action@1(State@1), {State@2, Result} end.