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, list_was_empty/0]).
-type non_empty_list(FOF) :: {non_empty_list, FOF, list(FOF)}.
-type list_was_empty() :: list_was_empty.
-spec first(non_empty_list(FOR)) -> FOR.
first(List) ->
erlang:element(2, List).
-spec do_index_map(
list(FPU),
list(FPW),
integer(),
fun((integer(), FPU) -> FPW)
) -> list(FPW).
do_index_map(List, Accumulator, Index, Fun) ->
case List of
[] ->
gleam@list:reverse(Accumulator);
[First | Rest] ->
do_index_map(
Rest,
[Fun(Index, First) | Accumulator],
Index + 1,
Fun
)
end.
-spec last(non_empty_list(FQC)) -> FQC.
last(List) ->
_pipe = gleam@list:last(erlang:element(3, List)),
gleam@result:unwrap(_pipe, erlang:element(2, List)).
-spec new(FRA, list(FRA)) -> non_empty_list(FRA).
new(First, Rest) ->
{non_empty_list, First, Rest}.
-spec append_list(non_empty_list(FOK), list(FOK)) -> non_empty_list(FOK).
append_list(First, Second) ->
new(
erlang:element(2, First),
gleam@list:append(erlang:element(3, First), Second)
).
-spec from_list(list(FPL)) -> {ok, non_empty_list(FPL)} |
{error, list_was_empty()}.
from_list(List) ->
case List of
[] ->
{error, list_was_empty};
[First | Rest] ->
{ok, new(First, Rest)}
end.
-spec index_map(non_empty_list(FPQ), fun((integer(), FPQ) -> FPS)) -> non_empty_list(FPS).
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(FPZ), FPZ) -> non_empty_list(FPZ).
intersperse(List, Elem) ->
new(
erlang:element(2, List),
[Elem | gleam@list:intersperse(erlang:element(3, List), Elem)]
).
-spec map(non_empty_list(FQE), fun((FQE) -> FQG)) -> non_empty_list(FQG).
map(List, Fun) ->
new(
Fun(erlang:element(2, List)),
gleam@list:map(erlang:element(3, List), Fun)
).
-spec prepend(non_empty_list(FRD), FRD) -> non_empty_list(FRD).
prepend(List, Item) ->
new(Item, [erlang:element(2, List) | erlang:element(3, List)]).
-spec reduce(non_empty_list(FRG), fun((FRG, FRG) -> FRG)) -> FRG.
reduce(List, Fun) ->
gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun).
-spec rest(non_empty_list(FRI)) -> list(FRI).
rest(List) ->
erlang:element(3, List).
-spec single(FRV) -> non_empty_list(FRV).
single(First) ->
new(First, []).
-spec to_list(non_empty_list(FSK)) -> list(FSK).
to_list(Non_empty) ->
[erlang:element(2, Non_empty) | erlang:element(3, Non_empty)].
-spec append(non_empty_list(FOG), non_empty_list(FOG)) -> non_empty_list(FOG).
append(First, Second) ->
new(
erlang:element(2, First),
gleam@list:append(erlang:element(3, First), to_list(Second))
).
-spec drop(non_empty_list(FOO), integer()) -> list(FOO).
drop(List, N) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
gleam@list:drop(_pipe@1, N).
-spec reverse_and_prepend(non_empty_list(FPH), non_empty_list(FPH)) -> non_empty_list(FPH).
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(FRL)) -> non_empty_list(FRL).
reverse(List) ->
_assert_subject = begin
_pipe = List,
_pipe@1 = to_list(_pipe),
_pipe@2 = gleam@list: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 => 416})
end,
Reversed.
-spec do_flatten(list(non_empty_list(FPC)), non_empty_list(FPC)) -> non_empty_list(FPC).
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(FOY))) -> non_empty_list(FOY).
flatten(Lists) ->
do_flatten(erlang:element(3, Lists), reverse(erlang:element(2, Lists))).
-spec flat_map(non_empty_list(FOT), fun((FOT) -> non_empty_list(FOV))) -> non_empty_list(FOV).
flat_map(List, Fun) ->
_pipe = List,
_pipe@1 = map(_pipe, Fun),
flatten(_pipe@1).
-spec do_map2(non_empty_list(FQO), list(FQQ), list(FQS), fun((FQQ, FQS) -> FQO)) -> non_empty_list(FQO).
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(FQI), non_empty_list(FQK), fun((FQI, FQK) -> FQM)) -> non_empty_list(FQM).
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(FQV), FQX, fun((FQX, FQV) -> {FQX, FQY})) -> {FQX,
non_empty_list(FQY)}.
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(FRO), FRQ, fun((FRQ, FRO) -> FRQ)) -> non_empty_list(FRQ).
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 => 438})
end,
Scanned.
-spec shuffle(non_empty_list(FRS)) -> non_empty_list(FRS).
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 => 461})
end,
Shuffled.
-spec sort(non_empty_list(FRX), fun((FRX, FRX) -> gleam@order:order())) -> non_empty_list(FRX).
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 => 497})
end,
Sorted.
-spec take(non_empty_list(FSH), integer()) -> list(FSH).
take(List, N) ->
_pipe = List,
_pipe@1 = to_list(_pipe),
gleam@list:take(_pipe@1, N).
-spec unique(non_empty_list(FSN)) -> non_empty_list(FSN).
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 => 595})
end,
Unique.
-spec unzip(non_empty_list({FSQ, FSR})) -> {non_empty_list(FSQ),
non_empty_list(FSR)}.
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(FSV), non_empty_list(FSX)) -> non_empty_list({FSV, FSX}).
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(FSA), non_empty_list(FSC)) -> {ok,
non_empty_list({FSA, FSC})} |
{error, gleam@list:length_mismatch()}.
strict_zip(List, Other) ->
case gleam@list:length(to_list(List)) =:= gleam@list:length(to_list(Other)) of
true ->
{ok, zip(List, Other)};
false ->
{error, length_mismatch}
end.