Current section
Files
Jump to
Current section
Files
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, 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(FNE),
list(FNG),
integer(),
fun((integer(), FNE) -> FNG)
) -> list(FNG).
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(FNM)) -> FNM.
last(List) ->
_pipe = gleam@list:last(erlang:element(3, List)),
gleam@result:unwrap(_pipe, erlang:element(2, List)).
-spec new(FOK, list(FOK)) -> non_empty_list(FOK).
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(FNA), fun((integer(), FNA) -> FNC)) -> non_empty_list(FNC).
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(FNJ), FNJ) -> non_empty_list(FNJ).
intersperse(List, Elem) ->
new(
erlang:element(2, List),
[Elem | gleam@list:intersperse(erlang:element(3, List), Elem)]
).
-spec map(non_empty_list(FNO), fun((FNO) -> FNQ)) -> non_empty_list(FNQ).
map(List, Fun) ->
new(
Fun(erlang:element(2, List)),
gleam@list:map(erlang:element(3, List), Fun)
).
-spec prepend(non_empty_list(FON), FON) -> non_empty_list(FON).
prepend(List, Item) ->
new(Item, [erlang:element(2, List) | erlang:element(3, List)]).
-spec reduce(non_empty_list(FOQ), fun((FOQ, FOQ) -> FOQ)) -> FOQ.
reduce(List, Fun) ->
gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun).
-spec rest(non_empty_list(FOS)) -> list(FOS).
rest(List) ->
erlang:element(3, List).
-spec single(FPF) -> non_empty_list(FPF).
single(First) ->
new(First, []).
-spec to_list(non_empty_list(FPU)) -> list(FPU).
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 reverse(non_empty_list(FOV)) -> non_empty_list(FOV).
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 => 427})
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(FNY), list(FOA), list(FOC), fun((FOA, FOC) -> FNY)) -> non_empty_list(FNY).
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(FNS), non_empty_list(FNU), fun((FNS, FNU) -> FNW)) -> non_empty_list(FNW).
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(FOF), FOH, fun((FOH, FOF) -> {FOH, FOI})) -> {FOH,
non_empty_list(FOI)}.
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(FOY), FPA, fun((FPA, FOY) -> FPA)) -> non_empty_list(FPA).
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 => 450})
end,
Scanned.
-spec shuffle(non_empty_list(FPC)) -> non_empty_list(FPC).
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 => 473})
end,
Shuffled.
-spec sort(non_empty_list(FPH), fun((FPH, FPH) -> gleam@order:order())) -> non_empty_list(FPH).
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 => 510})
end,
Sorted.
-spec take(non_empty_list(FPR), integer()) -> list(FPR).
take(List, N) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
gleam@list:take(_pipe@1, N).
-spec unique(non_empty_list(FPX)) -> non_empty_list(FPX).
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 => 611})
end,
Unique.
-spec unzip(non_empty_list({FQA, FQB})) -> {non_empty_list(FQA),
non_empty_list(FQB)}.
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(FQF), non_empty_list(FQH)) -> non_empty_list({FQF, FQH}).
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(FPK), non_empty_list(FPM)) -> {ok,
non_empty_list({FPK, FPM})} |
{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.