Current section

Files

Jump to
non_empty_list src non_empty_list.erl
Raw

src/non_empty_list.erl

-module(non_empty_list).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([first/1, last/1, new/2, append_list/2, from_list/1, index_map/2, intersperse/2, map/2, prepend/2, reduce/2, rest/1, single/1, to_list/1, append/2, drop/2, group/2, reverse/1, flatten/1, flat_map/2, map2/3, map_fold/3, scan/3, shuffle/1, sort/2, take/2, unique/1, unzip/1, zip/2, strict_zip/2]).
-export_type([non_empty_list/1]).
-type non_empty_list(FLP) :: {non_empty_list, FLP, list(FLP)}.
-spec first(non_empty_list(FMB)) -> FMB.
first(List) ->
erlang:element(2, List).
-spec do_index_map(
list(FNK),
list(FNM),
integer(),
fun((integer(), FNK) -> FNM)
) -> list(FNM).
do_index_map(List, Accumulator, Index, Fun) ->
case List of
[] ->
lists:reverse(Accumulator);
[First | Rest] ->
do_index_map(
Rest,
[Fun(Index, First) | Accumulator],
Index + 1,
Fun
)
end.
-spec last(non_empty_list(FNS)) -> FNS.
last(List) ->
_pipe = gleam@list:last(erlang:element(3, List)),
gleam@result:unwrap(_pipe, erlang:element(2, List)).
-spec new(FOQ, list(FOQ)) -> non_empty_list(FOQ).
new(First, Rest) ->
{non_empty_list, First, Rest}.
-spec append_list(non_empty_list(FLU), list(FLU)) -> non_empty_list(FLU).
append_list(First, Second) ->
new(
erlang:element(2, First),
lists:append(erlang:element(3, First), Second)
).
-spec from_list(list(FMV)) -> {ok, non_empty_list(FMV)} | {error, nil}.
from_list(List) ->
case List of
[] ->
{error, nil};
[First | Rest] ->
{ok, new(First, Rest)}
end.
-spec index_map(non_empty_list(FNG), fun((integer(), FNG) -> FNI)) -> non_empty_list(FNI).
index_map(List, Fun) ->
new(
Fun(0, erlang:element(2, List)),
do_index_map(erlang:element(3, List), [], 1, Fun)
).
-spec intersperse(non_empty_list(FNP), FNP) -> non_empty_list(FNP).
intersperse(List, Elem) ->
new(
erlang:element(2, List),
[Elem | gleam@list:intersperse(erlang:element(3, List), Elem)]
).
-spec map(non_empty_list(FNU), fun((FNU) -> FNW)) -> non_empty_list(FNW).
map(List, Fun) ->
new(
Fun(erlang:element(2, List)),
gleam@list:map(erlang:element(3, List), Fun)
).
-spec prepend(non_empty_list(FOT), FOT) -> non_empty_list(FOT).
prepend(List, Item) ->
new(Item, [erlang:element(2, List) | erlang:element(3, List)]).
-spec reduce(non_empty_list(FOW), fun((FOW, FOW) -> FOW)) -> FOW.
reduce(List, Fun) ->
gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun).
-spec rest(non_empty_list(FOY)) -> list(FOY).
rest(List) ->
erlang:element(3, List).
-spec single(FPL) -> non_empty_list(FPL).
single(First) ->
new(First, []).
-spec to_list(non_empty_list(FQA)) -> list(FQA).
to_list(Non_empty) ->
[erlang:element(2, Non_empty) | erlang:element(3, Non_empty)].
-spec append(non_empty_list(FLQ), non_empty_list(FLQ)) -> non_empty_list(FLQ).
append(First, Second) ->
new(
erlang:element(2, First),
lists:append(erlang:element(3, First), to_list(Second))
).
-spec drop(non_empty_list(FLY), integer()) -> list(FLY).
drop(List, N) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
gleam@list:drop(_pipe@1, N).
-spec reverse_and_prepend(non_empty_list(FMR), non_empty_list(FMR)) -> non_empty_list(FMR).
reverse_and_prepend(Prefix, Suffix) ->
case erlang:element(3, Prefix) of
[] ->
new(erlang:element(2, Prefix), to_list(Suffix));
[First | Rest] ->
reverse_and_prepend(
new(First, Rest),
new(erlang:element(2, Prefix), to_list(Suffix))
)
end.
-spec group(non_empty_list(FNA), fun((FNA) -> FNC)) -> gleam@dict:dict(FNC, non_empty_list(FNA)).
group(List, Key) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list:group(_pipe@1, Key),
gleam@dict:map_values(
_pipe@2,
fun(_, Group) ->
_assert_subject = from_list(Group),
{ok, Group@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"group"/utf8>>,
line => 222})
end,
Group@1
end
).
-spec reverse(non_empty_list(FPB)) -> non_empty_list(FPB).
reverse(List) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = lists:reverse(_pipe@1),
from_list(_pipe@2)
end,
{ok, Reversed} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"reverse"/utf8>>,
line => 474})
end,
Reversed.
-spec do_flatten(list(non_empty_list(FMM)), non_empty_list(FMM)) -> non_empty_list(FMM).
do_flatten(Lists, Accumulator) ->
case Lists of
[] ->
reverse(Accumulator);
[List | Further_lists] ->
do_flatten(Further_lists, reverse_and_prepend(List, Accumulator))
end.
-spec flatten(non_empty_list(non_empty_list(FMI))) -> non_empty_list(FMI).
flatten(Lists) ->
do_flatten(erlang:element(3, Lists), reverse(erlang:element(2, Lists))).
-spec flat_map(non_empty_list(FMD), fun((FMD) -> non_empty_list(FMF))) -> non_empty_list(FMF).
flat_map(List, Fun) ->
_pipe = List,
_pipe@1 = map(_pipe, Fun),
flatten(_pipe@1).
-spec do_map2(non_empty_list(FOE), list(FOG), list(FOI), fun((FOG, FOI) -> FOE)) -> non_empty_list(FOE).
do_map2(Acc, List1, List2, Fun) ->
case {List1, List2} of
{[], _} ->
reverse(Acc);
{_, []} ->
reverse(Acc);
{[First_a | Rest_as], [First_b | Rest_bs]} ->
_pipe = prepend(Acc, Fun(First_a, First_b)),
do_map2(_pipe, Rest_as, Rest_bs, Fun)
end.
-spec map2(non_empty_list(FNY), non_empty_list(FOA), fun((FNY, FOA) -> FOC)) -> non_empty_list(FOC).
map2(List1, List2, Fun) ->
do_map2(
single(Fun(erlang:element(2, List1), erlang:element(2, List2))),
erlang:element(3, List1),
erlang:element(3, List2),
Fun
).
-spec map_fold(non_empty_list(FOL), FON, fun((FON, FOL) -> {FON, FOO})) -> {FON,
non_empty_list(FOO)}.
map_fold(List, Acc, Fun) ->
{Acc@1, First_elem} = Fun(Acc, erlang:element(2, List)),
_pipe = gleam@list:fold(
erlang:element(3, List),
{Acc@1, single(First_elem)},
fun(Acc_non_empty, Item) ->
{Acc@2, Non_empty} = Acc_non_empty,
{Acc@3, New_item} = Fun(Acc@2, Item),
{Acc@3, prepend(Non_empty, New_item)}
end
),
gleam@pair:map_second(_pipe, fun reverse/1).
-spec scan(non_empty_list(FPE), FPG, fun((FPG, FPE) -> FPG)) -> non_empty_list(FPG).
scan(List, Initial, Fun) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list:scan(_pipe@1, Initial, Fun),
from_list(_pipe@2)
end,
{ok, Scanned} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"scan"/utf8>>,
line => 497})
end,
Scanned.
-spec shuffle(non_empty_list(FPI)) -> non_empty_list(FPI).
shuffle(List) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list:shuffle(_pipe@1),
from_list(_pipe@2)
end,
{ok, Shuffled} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"shuffle"/utf8>>,
line => 520})
end,
Shuffled.
-spec sort(non_empty_list(FPN), fun((FPN, FPN) -> gleam@order:order())) -> non_empty_list(FPN).
sort(List, Compare) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list:sort(_pipe@1, Compare),
from_list(_pipe@2)
end,
{ok, Sorted} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"sort"/utf8>>,
line => 557})
end,
Sorted.
-spec take(non_empty_list(FPX), integer()) -> list(FPX).
take(List, N) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
gleam@list:take(_pipe@1, N).
-spec unique(non_empty_list(FQD)) -> non_empty_list(FQD).
unique(List) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list:unique(_pipe@1),
from_list(_pipe@2)
end,
{ok, Unique} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"non_empty_list"/utf8>>,
function => <<"unique"/utf8>>,
line => 658})
end,
Unique.
-spec unzip(non_empty_list({FQG, FQH})) -> {non_empty_list(FQG),
non_empty_list(FQH)}.
unzip(List) ->
_pipe = gleam@list:unzip(erlang:element(3, List)),
_pipe@1 = gleam@pair:map_first(
_pipe,
fun(_capture) ->
new(erlang:element(1, erlang:element(2, List)), _capture)
end
),
gleam@pair:map_second(
_pipe@1,
fun(_capture@1) ->
new(erlang:element(2, erlang:element(2, List)), _capture@1)
end
).
-spec zip(non_empty_list(FQL), non_empty_list(FQN)) -> non_empty_list({FQL, FQN}).
zip(List, Other) ->
new(
{erlang:element(2, List), erlang:element(2, Other)},
gleam@list:zip(erlang:element(3, List), erlang:element(3, Other))
).
-spec strict_zip(non_empty_list(FPQ), non_empty_list(FPS)) -> {ok,
non_empty_list({FPQ, FPS})} |
{error, nil}.
strict_zip(List, Other) ->
case erlang:length(to_list(List)) =:= erlang:length(to_list(Other)) of
true ->
{ok, zip(List, Other)};
false ->
{error, nil}
end.