Current section
Files
Jump to
Current section
Files
src/argamak@space.erl
-module(argamak@space).
-compile(no_auto_import).
-export([new/0, d1/1, d2/2, d3/3, d4/4, d5/5, d6/6, from_list/1, axes/1, degree/1, shape/1, map/2, merge/2, to_string/1]).
-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 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 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 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,
case case Errors of
[] ->
_pipe@13 = X@2,
_pipe@14 = gleam@result:all(_pipe@13),
gleam@result:map_error(_pipe@14, fun(Error) -> [Error] end);
_@1 ->
_pipe@15 = Errors,
_pipe@16 = gleam@list:map(
_pipe@15,
fun(X@3) ->
{error, X@5} = case X@3 of
{error, X@4} -> {error, X@4};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"argamak/space"/utf8>>,
function => <<"merge"/utf8>>,
line => 370})
end,
X@5
end
),
{error, _pipe@16}
end of
{error, _try@1} -> {error, _try@1};
{ok, X@6} ->
_pipe@17 = X@6,
_pipe@18 = {space, _pipe@17},
validate(_pipe@18)
end.
-spec to_string(space()) -> binary().
to_string(X) ->
Axes = begin
_pipe = X,
_pipe@1 = axes(_pipe),
_pipe@4 = gleam@list:map(
_pipe@1,
fun(X@1) ->
Name = argamak@axis:name(X@1),
Size = begin
_pipe@2 = X@1,
_pipe@3 = argamak@axis:size(_pipe@2),
gleam@int:to_string(_pipe@3)
end,
case X@1 of
{axis, _@1, _@2} ->
<<<<<<<<"Axis(\""/utf8, Name/binary>>/binary,
"\", "/utf8>>/binary,
Size/binary>>/binary,
")"/utf8>>;
{infer, _@3} ->
<<<<"Infer(\""/utf8, Name/binary>>/binary, "\")"/utf8>>;
_@4 ->
<<<<<<Name/binary, "("/utf8>>/binary, Size/binary>>/binary,
")"/utf8>>
end
end
),
gleam@string:join(_pipe@4, <<", "/utf8>>)
end,
<<<<"Space("/utf8, Axes/binary>>/binary, ")"/utf8>>.
-spec validate(space()) -> {ok, space()} | {error, list(space_error())}.
validate(Space) ->
{validate_acc, _@2, _@3, Results} = begin
_pipe = Space,
_pipe@1 = axes(_pipe),
gleam@list:fold(
_pipe@1,
{validate_acc, [], false, []},
fun(Acc, Axis) ->
Name = argamak@axis:name(Axis),
Size = argamak@axis:size(Axis),
Errors = begin
_pipe@2 = [{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@3 = gleam@list:map(
_pipe@2,
fun(Invalid) -> case erlang:element(3, Invalid) of
false ->
[];
true ->
[{space_error,
erlang:element(2, Invalid),
[Axis]}]
end end
),
gleam@list:flatten(_pipe@3)
end,
Result = case Errors of
[] ->
{ok, Axis};
_@1 ->
{error, Errors}
end,
{validate_acc,
[Name | erlang:element(2, Acc)],
erlang:element(3, Acc)
orelse (Axis
=:= {infer, Name}),
[Result | erlang:element(4, Acc)]}
end
)
end,
case gleam@list:any(Results, fun gleam@result:is_error/1) of
false ->
{ok, Space};
true ->
_pipe@4 = Results,
_pipe@5 = gleam@list:reverse(_pipe@4),
_pipe@6 = gleam@list:map(_pipe@5, fun(Result@1) -> case Result@1 of
{ok, _@4} ->
[];
{error, Errors@1} ->
Errors@1
end end),
_pipe@7 = gleam@list:flatten(_pipe@6),
{error, _pipe@7}
end.