-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(EGR, EGS, EGT) :: {eval, fun((EGT) -> {EGT, {ok, EGR} | {error, EGS}})}. -spec run(eval(EGW, EGX, EGY), EGY) -> {ok, EGW} | {error, EGX}. run(Eval, Context) -> _pipe = runwrap(Eval, Context), gleam@pair:second(_pipe). -spec runwrap(eval(EHE, EHF, EHG), EHG) -> {EHG, {ok, EHE} | {error, EHF}}. runwrap(Eval, Ctx) -> {eval, Eval@1} = Eval, Eval@1(Ctx). -spec succeed(EHM) -> eval(EHM, any(), any()). succeed(Value) -> {eval, fun(Ctx) -> {Ctx, {ok, Value}} end}. -spec succeed2(fun((EHS, EHT) -> EHU)) -> eval(fun((EHS) -> fun((EHT) -> EHU)), any(), any()). succeed2(F) -> _pipe = gleam@function:curry2(F), succeed(_pipe). -spec succeed3(fun((EIA, EIB, EIC) -> EID)) -> eval(fun((EIA) -> fun((EIB) -> fun((EIC) -> EID))), any(), any()). succeed3(F) -> _pipe = gleam@function:curry3(F), succeed(_pipe). -spec succeed4(fun((EIJ, EIK, EIL, EIM) -> EIN)) -> eval(fun((EIJ) -> fun((EIK) -> fun((EIL) -> fun((EIM) -> EIN)))), EIN, any()). succeed4(F) -> _pipe = gleam@function:curry4(F), succeed(_pipe). -spec succeed5(fun((EIS, EIT, EIU, EIV, EIW) -> EIX)) -> eval(fun((EIS) -> fun((EIT) -> fun((EIU) -> fun((EIV) -> fun((EIW) -> EIX))))), EIW, any()). succeed5(F) -> _pipe = gleam@function:curry5(F), succeed(_pipe). -spec succeed6(fun((EJC, EJD, EJE, EJF, EJG, EJH) -> EJI)) -> eval(fun((EJC) -> fun((EJD) -> fun((EJE) -> fun((EJF) -> fun((EJG) -> fun((EJH) -> EJI)))))), EJG, any()). succeed6(F) -> _pipe = gleam@function:curry6(F), succeed(_pipe). -spec throw(EJN) -> eval(any(), EJN, any()). throw(Error) -> {eval, fun(Ctx) -> {Ctx, {error, Error}} end}. -spec from(fun((EJT) -> {EJT, {ok, EJU} | {error, EJV}})) -> eval(EJU, EJV, EJT). from(Eval) -> {eval, Eval}. -spec from_option(gleam@option:option(EKB), EKD) -> eval(EKB, EKD, any()). from_option(Value, Error) -> case Value of {some, A} -> succeed(A); none -> throw(Error) end. -spec from_result({ok, EKI} | {error, EKJ}) -> eval(EKI, EKJ, any()). from_result(Value) -> case Value of {ok, A} -> succeed(A); {error, E} -> throw(E) end. -spec map(eval(EKQ, EKR, EKS), fun((EKQ) -> EKW)) -> eval(EKW, EKR, EKS). 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(ELA, ELB, ELC), eval(ELG, ELB, ELC), fun((ELA, ELG) -> ELK)) -> eval(ELK, ELB, ELC). 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(ELO, ELP, ELQ), fun((ELP) -> ELU)) -> eval(ELO, ELU, ELQ). 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(), ELZ, EMA), EME) -> eval(EME, ELZ, EMA). 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(EMI, any(), EMK), EMO) -> eval(EMI, EMO, EMK). 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((EMS) -> EMT), EMU, EMV), eval(EMS, EMU, EMV)) -> eval(EMT, EMU, EMV). apply(Eval_f, Eval_a) -> map2(Eval_f, Eval_a, fun(F, A) -> F(A) end). -spec then(eval(ENF, ENG, ENH), fun((ENF) -> eval(ENL, ENG, ENH))) -> eval(ENL, ENG, ENH). 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(ENS, ENT, ENU))) -> eval(list(ENS), ENT, ENU). 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(EOD, EOE, EOF), fun((EOE, EOF) -> eval(EOD, EOE, EOF))) -> eval(EOD, EOE, EOF). attempt(Eval, F) -> {eval, fun(Ctx) -> {Ctx_, Result} = runwrap(Eval, Ctx), case Result of {ok, A} -> {Ctx_, {ok, A}}; {error, E} -> runwrap(F(E, Ctx_), Ctx) end end}.