-module(validate_monadic). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([error/1, succeed/1, map/2, map_error/2, and_also/2, compose/3, and_then/2, and_map/2]). -spec error(FJZ) -> {ok, any()} | {error, {FJZ, list(FJZ)}}. error(Err) -> {error, {Err, []}}. -spec succeed(FKE) -> {ok, FKE} | {error, {FKF, list(FKF)}}. succeed(A) -> {ok, A}. -spec map({ok, FKI} | {error, {FKJ, list(FKJ)}}, fun((FKI) -> FKM)) -> {ok, FKM} | {error, {FKJ, list(FKJ)}}. map(Validation, Map_fn) -> gleam@result:map(Validation, Map_fn). -spec map_error({ok, FKP} | {error, {FKQ, list(FKQ)}}, fun((FKQ) -> FKT)) -> {ok, FKP} | {error, {FKT, list(FKT)}}. map_error(Validation, Map_fn) -> case Validation of {ok, V} -> {ok, V}; {error, {Head, Rest}} -> {error, {Map_fn(Head), gleam@list:map(Rest, Map_fn)}} end. -spec and_also( {ok, FLG} | {error, {FLH, list(FLH)}}, {ok, FLG} | {error, {FLH, list(FLH)}} ) -> {ok, FLG} | {error, {FLH, list(FLH)}}. and_also(Validation_a, Validation_b) -> case {Validation_a, Validation_b} of {{ok, _}, {ok, A}} -> {ok, A}; {{error, {Err_a_head, Err_a_rest}}, {error, {Err_b_head, Err_b_rest}}} -> {error, {Err_a_head, gleam@list:concat( [Err_a_rest, gleam@list:prepend(Err_b_rest, Err_b_head)] )}}; {{error, Err}, _} -> {error, Err}; {_, {error, Err@1}} -> {error, Err@1} end. -spec compose( FKW, fun((FKW) -> {ok, FKX} | {error, {FKY, list(FKY)}}), list(fun((FKW) -> {ok, FKX} | {error, {FKY, list(FKY)}})) ) -> {ok, FKX} | {error, {FKY, list(FKY)}}. compose(Input, Validation, Validations) -> gleam@list:fold( Validations, Validation(Input), fun(Acc, Cur) -> and_also(Acc, Cur(Input)) end ). -spec and_then( {ok, FLO} | {error, {FLP, list(FLP)}}, fun((FLO) -> {ok, FLS} | {error, {FLP, list(FLP)}}) ) -> {ok, FLS} | {error, {FLP, list(FLP)}}. and_then(Validation, Bind_fn) -> gleam@result:then(Validation, Bind_fn). -spec and_map( {ok, fun((FLX) -> FLY)} | {error, {FLZ, list(FLZ)}}, {ok, FLX} | {error, {FLZ, list(FLZ)}} ) -> {ok, FLY} | {error, {FLZ, list(FLZ)}}. and_map(Prev_validation, Validation) -> case Prev_validation of {ok, Apply} -> case Validation of {ok, A} -> {ok, Apply(A)}; {error, Err} -> {error, Err} end; {error, {Prev_err_head, Prev_err_rest}} -> case Validation of {ok, _} -> {error, {Prev_err_head, Prev_err_rest}}; {error, {Next_err_head, Next_err_rest}} -> {error, {Prev_err_head, gleam@list:flatten( [Prev_err_rest, gleam@list:prepend( Next_err_rest, Next_err_head )] )}} end end.