-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.