-module(non_empty_list). -compile([no_auto_import, nowarn_unused_vars]). -export([from_list/1, fold/3, count/1, filter/2, to_list/1, reverse/1, map/2]). -export_type([non_empty_list/1]). -type non_empty_list(GVL) :: {'end', GVL} | {next, GVL, non_empty_list(GVL)}. -spec from_list(list(GWB)) -> {ok, non_empty_list(GWB)} | {error, nil}. from_list(List) -> case List of [] -> {error, nil}; [X | Xs] -> {ok, gleam@list:fold( Xs, {'end', X}, fun(Acc, Item) -> {next, Item, Acc} end )} end. -spec fold(non_empty_list(GVM), GVO, fun((GVO, GVM) -> GVO)) -> GVO. fold(List, Initial, Fun) -> case List of {'end', Item} -> Fun(Initial, Item); {next, X, Xs} -> fold(Xs, Fun(Initial, X), Fun) end. -spec count(non_empty_list(any())) -> integer(). count(List) -> fold(List, 0, fun(Acc, _) -> Acc + 1 end). -spec filter(non_empty_list(GVV), fun((GVV) -> boolean())) -> list(GVV). filter(List, Predicate) -> _pipe = fold(List, [], fun(Acc, Item) -> case Predicate(Item) of true -> [Item | Acc]; false -> Acc end end), gleam@list:reverse(_pipe). -spec to_list(non_empty_list(GVY)) -> list(GVY). to_list(List) -> _pipe = fold(List, [], fun(Acc, Item) -> [Item | Acc] end), gleam@list:reverse(_pipe). -spec reverse(non_empty_list(GWG)) -> non_empty_list(GWG). reverse(List) -> case List of {'end', _} -> List; {next, X, Xs} -> fold(Xs, {'end', X}, fun(Acc, X@1) -> {next, X@1, Acc} end) end. -spec map(non_empty_list(GVR), fun((GVR) -> GVT)) -> non_empty_list(GVT). map(List, Transform) -> case List of {'end', X} -> {'end', Transform(X)}; {next, X@1, Xs} -> _pipe = fold( Xs, {'end', Transform(X@1)}, fun(Acc, Item) -> {next, Transform(Item), Acc} end ), reverse(_pipe) end.