Current section
Files
Jump to
Current section
Files
src/argamak@space.erl
-module(argamak@space).
-compile([no_auto_import, nowarn_unused_vars]).
-export([new/0, axes/1, degree/1, shape/1, to_string/1, d1/1, d2/2, d3/3, d4/4, d5/5, d6/6, from_list/1, map/2, merge/2]).
-export_type([space/0, space_error/0, validate_acc/0, invalid/0]).
-opaque space() :: {space, list(argamak@axis:axis())}.
-type space_error() :: cannot_merge |
cannot_infer |
duplicate_name |
invalid_size |
{space_error, space_error(), list(argamak@axis:axis())}.
-type validate_acc() :: {validate_acc,
list(binary()),
boolean(),
list({ok, argamak@axis:axis()} | {error, list(space_error())})}.
-type invalid() :: {invalid, space_error(), boolean()}.
-spec new() -> space().
new() ->
{space, []}.
-spec axes(space()) -> list(argamak@axis:axis()).
axes(X) ->
erlang:element(2, X).
-spec degree(space()) -> integer().
degree(X) ->
_pipe = X,
_pipe@1 = axes(_pipe),
gleam@list:length(_pipe@1).
-spec shape(space()) -> list(integer()).
shape(X) ->
_pipe = X,
_pipe@1 = axes(_pipe),
gleam@list:map(_pipe@1, fun argamak@axis:size/1).
-spec to_string(space()) -> binary().
to_string(X) ->
Axes = (gleam@list:map(
axes(X),
fun(X@1) ->
Name = argamak@axis:name(X@1),
Size = begin
_pipe = X@1,
_pipe@1 = argamak@axis:size(_pipe),
gleam@int:to_string(_pipe@1)
end,
case X@1 of
{axis, _, _} ->
<<<<<<<<"Axis(\""/utf8, Name/binary>>/binary, "\", "/utf8>>/binary,
Size/binary>>/binary,
")"/utf8>>;
{infer, _} ->
<<<<"Infer(\""/utf8, Name/binary>>/binary, "\")"/utf8>>;
_ ->
<<<<<<Name/binary, "("/utf8>>/binary, Size/binary>>/binary,
")"/utf8>>
end
end
)),
<<<<"Space("/utf8, (gleam@string:join(Axes, <<", "/utf8>>))/binary>>/binary,
")"/utf8>>.
-spec validate(space()) -> {ok, space()} | {error, list(space_error())}.
validate(Space) ->
{validate_acc, _, _, Results} = (gleam@list:fold(
axes(Space),
{validate_acc, [], false, []},
fun(Acc, Axis) ->
Name = argamak@axis:name(Axis),
Size = argamak@axis:size(Axis),
Errors = begin
_pipe = [{invalid,
duplicate_name,
gleam@list:contains(erlang:element(2, Acc), Name)},
{invalid,
cannot_infer,
erlang:element(3, Acc) andalso (Axis =:= {infer, Name})},
{invalid,
invalid_size,
(Size < 1) andalso (Axis /= {infer, Name})}],
_pipe@1 = gleam@list:map(
_pipe,
fun(Invalid) -> case erlang:element(3, Invalid) of
false ->
[];
true ->
[{space_error,
erlang:element(2, Invalid),
[Axis]}]
end end
),
gleam@list:flatten(_pipe@1)
end,
Result = case Errors of
[] ->
{ok, Axis};
_ ->
{error, Errors}
end,
{validate_acc,
[Name | erlang:element(2, Acc)],
erlang:element(3, Acc) orelse (Axis =:= {infer, Name}),
[Result | erlang:element(4, Acc)]}
end
)),
case gleam@list:any(Results, fun gleam@result:is_error/1) of
false ->
{ok, Space};
true ->
_pipe@2 = Results,
_pipe@3 = gleam@list:reverse(_pipe@2),
_pipe@4 = gleam@list:map(_pipe@3, fun(Result@1) -> case Result@1 of
{ok, _} ->
[];
{error, Errors@1} ->
Errors@1
end end),
_pipe@5 = gleam@list:flatten(_pipe@4),
{error, _pipe@5}
end.
-spec d1(argamak@axis:axis()) -> {ok, space()} | {error, list(space_error())}.
d1(A) ->
_pipe = [A],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec d2(argamak@axis:axis(), argamak@axis:axis()) -> {ok, space()} |
{error, list(space_error())}.
d2(A, B) ->
_pipe = [A, B],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec d3(argamak@axis:axis(), argamak@axis:axis(), argamak@axis:axis()) -> {ok,
space()} |
{error, list(space_error())}.
d3(A, B, C) ->
_pipe = [A, B, C],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec d4(
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis()
) -> {ok, space()} | {error, list(space_error())}.
d4(A, B, C, D) ->
_pipe = [A, B, C, D],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec d5(
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis()
) -> {ok, space()} | {error, list(space_error())}.
d5(A, B, C, D, E) ->
_pipe = [A, B, C, D, E],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec d6(
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis(),
argamak@axis:axis()
) -> {ok, space()} | {error, list(space_error())}.
d6(A, B, C, D, E, F) ->
_pipe = [A, B, C, D, E, F],
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec from_list(list(argamak@axis:axis())) -> {ok, space()} |
{error, list(space_error())}.
from_list(X) ->
_pipe = X,
_pipe@1 = {space, _pipe},
validate(_pipe@1).
-spec map(space(), fun((argamak@axis:axis()) -> argamak@axis:axis())) -> {ok,
space()} |
{error, list(space_error())}.
map(X, Fun) ->
_pipe = X,
_pipe@1 = axes(_pipe),
_pipe@2 = gleam@list:map(_pipe@1, Fun),
_pipe@3 = {space, _pipe@2},
validate(_pipe@3).
-spec merge(space(), space()) -> {ok, space()} | {error, list(space_error())}.
merge(A, B) ->
Index@1 = fun(X) -> _pipe = X,
_pipe@1 = axes(_pipe),
_pipe@2 = gleam@list:index_map(
_pipe@1,
fun(Index, Axis) -> {Index, Axis} end
),
gleam@map:from_list(_pipe@2) end,
A_index = Index@1(A),
B_index = Index@1(B),
A_size = gleam@map:size(A_index),
B_size = gleam@map:size(B_index),
{X@1, Map} = case A_size < B_size of
true ->
{axes(B), A_index};
false ->
{axes(A), B_index}
end,
Offset = gleam@int:absolute_value(A_size - B_size),
{X@2, Errors} = begin
_pipe@3 = X@1,
_pipe@12 = gleam@list:index_map(
_pipe@3,
fun(Index@2, A_axis) ->
B_axis = begin
_pipe@4 = Map,
_pipe@5 = gleam@map:get(_pipe@4, Index@2 - Offset),
gleam@result:unwrap(_pipe@5, A_axis)
end,
A_name = argamak@axis:name(A_axis),
B_name = argamak@axis:name(B_axis),
A_size@1 = argamak@axis:size(A_axis),
B_size@1 = argamak@axis:size(B_axis),
Should_infer = (A_axis =:= {infer, A_name}) orelse (B_axis =:= {infer,
B_name}),
case A_name =:= B_name of
true when Should_infer ->
_pipe@6 = A_name,
_pipe@7 = {infer, _pipe@6},
{ok, _pipe@7};
true ->
_pipe@8 = A_axis,
_pipe@9 = argamak@axis:resize(
_pipe@8,
gleam@int:max(A_size@1, B_size@1)
),
{ok, _pipe@9};
false ->
_pipe@10 = cannot_merge,
_pipe@11 = {space_error, _pipe@10, [A_axis, B_axis]},
{error, _pipe@11}
end
end
),
gleam@list:partition(_pipe@12, fun gleam@result:is_ok/1)
end,
gleam@result:'try'(case Errors of
[] ->
_pipe@13 = X@2,
_pipe@14 = gleam@result:all(_pipe@13),
gleam@result:map_error(_pipe@14, fun(Error) -> [Error] end);
_ ->
_pipe@15 = Errors,
_pipe@16 = gleam@list:map(
_pipe@15,
fun(X@3) ->
{error, X@4} = case X@3 of
{error, _} -> X@3;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"argamak/space"/utf8>>,
function => <<"merge"/utf8>>,
line => 370})
end,
X@4
end
),
{error, _pipe@16}
end, fun(X@5) -> _pipe@17 = X@5,
_pipe@18 = {space, _pipe@17},
validate(_pipe@18) end).