Packages

A Gleam package to help you thread state through a series of steps.

Current section

Files

Jump to
eval src eval.erl
Raw

src/eval.erl

-module(eval).
-compile(no_auto_import).
-export([run/2, succeed/1, succeed2/1, succeed3/1, succeed4/1, succeed5/1, succeed6/1, throw/1, from/1, from_option/2, from_result/1, map/2, map2/3, map_error/2, replace/2, replace_error/2, apply/2, then/2, all/1, attempt/2]).
-export_type([eval/3]).
-opaque eval(EHB, EHC, EHD) :: {eval,
fun((EHD) -> {EHD, {ok, EHB} | {error, EHC}})}.
-spec run(eval(EHG, EHH, EHI), EHI) -> {ok, EHG} | {error, EHH}.
run(Eval, Context) ->
_pipe = runwrap(Eval, Context),
gleam@pair:second(_pipe).
-spec runwrap(eval(EHO, EHP, EHQ), EHQ) -> {EHQ, {ok, EHO} | {error, EHP}}.
runwrap(Eval, Ctx) ->
{eval, Eval@1} = Eval,
Eval@1(Ctx).
-spec succeed(EHW) -> eval(EHW, any(), any()).
succeed(Value) ->
{eval, fun(Ctx) -> {Ctx, {ok, Value}} end}.
-spec succeed2(fun((EIC, EID) -> EIE)) -> eval(fun((EIC) -> fun((EID) -> EIE)), any(), any()).
succeed2(F) ->
_pipe = gleam@function:curry2(F),
succeed(_pipe).
-spec succeed3(fun((EIK, EIL, EIM) -> EIN)) -> eval(fun((EIK) -> fun((EIL) -> fun((EIM) -> EIN))), any(), any()).
succeed3(F) ->
_pipe = gleam@function:curry3(F),
succeed(_pipe).
-spec succeed4(fun((EIT, EIU, EIV, EIW) -> EIX)) -> eval(fun((EIT) -> fun((EIU) -> fun((EIV) -> fun((EIW) -> EIX)))), EIX, any()).
succeed4(F) ->
_pipe = gleam@function:curry4(F),
succeed(_pipe).
-spec succeed5(fun((EJC, EJD, EJE, EJF, EJG) -> EJH)) -> eval(fun((EJC) -> fun((EJD) -> fun((EJE) -> fun((EJF) -> fun((EJG) -> EJH))))), EJG, any()).
succeed5(F) ->
_pipe = gleam@function:curry5(F),
succeed(_pipe).
-spec succeed6(fun((EJM, EJN, EJO, EJP, EJQ, EJR) -> EJS)) -> eval(fun((EJM) -> fun((EJN) -> fun((EJO) -> fun((EJP) -> fun((EJQ) -> fun((EJR) -> EJS)))))), EJQ, any()).
succeed6(F) ->
_pipe = gleam@function:curry6(F),
succeed(_pipe).
-spec throw(EJX) -> eval(any(), EJX, any()).
throw(Error) ->
{eval, fun(Ctx) -> {Ctx, {error, Error}} end}.
-spec from(fun((EKD) -> {EKD, {ok, EKE} | {error, EKF}})) -> eval(EKE, EKF, EKD).
from(Eval) ->
{eval, Eval}.
-spec from_option(gleam@option:option(EKL), EKN) -> eval(EKL, EKN, any()).
from_option(Value, Error) ->
case Value of
{some, A} ->
succeed(A);
none ->
throw(Error)
end.
-spec from_result({ok, EKS} | {error, EKT}) -> eval(EKS, EKT, any()).
from_result(Value) ->
case Value of
{ok, A} ->
succeed(A);
{error, E} ->
throw(E)
end.
-spec map(eval(ELA, ELB, ELC), fun((ELA) -> ELG)) -> eval(ELG, ELB, ELC).
map(Eval, F) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result} = runwrap(Eval, Ctx),
case Result of
{ok, A} ->
{Ctx@1, {ok, F(A)}};
{error, E} ->
{Ctx@1, {error, E}}
end
end}.
-spec map2(eval(ELK, ELL, ELM), eval(ELQ, ELL, ELM), fun((ELK, ELQ) -> ELU)) -> eval(ELU, ELL, ELM).
map2(Eval_a, Eval_b, F) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result1} = runwrap(Eval_a, Ctx),
case Result1 of
{ok, A} ->
{Ctx@2, Result2} = runwrap(Eval_b, Ctx@1),
case Result2 of
{ok, B} ->
{Ctx@2, {ok, F(A, B)}};
{error, E} ->
{Ctx@2, {error, E}}
end;
{error, E@1} ->
{Ctx@1, {error, E@1}}
end
end}.
-spec map_error(eval(ELY, ELZ, EMA), fun((ELZ) -> EME)) -> eval(ELY, EME, EMA).
map_error(Eval, F) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result} = runwrap(Eval, Ctx),
case Result of
{ok, A} ->
{Ctx@1, {ok, A}};
{error, E} ->
{Ctx@1, {error, F(E)}}
end
end}.
-spec replace(eval(any(), EMJ, EMK), EMO) -> eval(EMO, EMJ, EMK).
replace(Eval, Replacement) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result} = runwrap(Eval, Ctx),
case Result of
{ok, _@1} ->
{Ctx@1, {ok, Replacement}};
{error, E} ->
{Ctx@1, {error, E}}
end
end}.
-spec replace_error(eval(EMS, any(), EMU), EMY) -> eval(EMS, EMY, EMU).
replace_error(Eval, Replacement) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result} = runwrap(Eval, Ctx),
case Result of
{ok, A} ->
{Ctx@1, {ok, A}};
{error, _@1} ->
{Ctx@1, {error, Replacement}}
end
end}.
-spec apply(eval(fun((ENC) -> END), ENE, ENF), eval(ENC, ENE, ENF)) -> eval(END, ENE, ENF).
apply(Eval_f, Eval_a) ->
map2(Eval_f, Eval_a, fun(F, A) -> F(A) end).
-spec then(eval(ENP, ENQ, ENR), fun((ENP) -> eval(ENV, ENQ, ENR))) -> eval(ENV, ENQ, ENR).
then(Eval, F) ->
{eval,
fun(Ctx) ->
{Ctx@1, Result} = runwrap(Eval, Ctx),
case Result of
{ok, A} ->
runwrap(F(A), Ctx@1);
{error, E} ->
{Ctx@1, {error, E}}
end
end}.
-spec all(list(eval(EOC, EOD, EOE))) -> eval(list(EOC), EOD, EOE).
all(Evals) ->
Prepend = fun(List, A) -> [A | List] end,
Callback = fun(A@1, List@1) -> map2(A@1, List@1, Prepend) end,
_pipe = gleam@list:fold(Evals, succeed([]), Callback),
map(_pipe, fun gleam@list:reverse/1).
-spec attempt(eval(EON, EOO, EOP), fun((EOP, EOO) -> eval(EON, EOO, EOP))) -> eval(EON, EOO, EOP).
attempt(Eval, F) ->
{eval,
fun(Ctx) ->
{Ctx_, Result} = runwrap(Eval, Ctx),
case Result of
{ok, A} ->
{Ctx_, {ok, A}};
{error, E} ->
runwrap(F(Ctx_, E), Ctx)
end
end}.