Current section
Files
Jump to
Current section
Files
src/validate_monadic.erl
-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.