Current section

Files

Jump to
gleam_stdlib gen src gleam@iterator.erl
Raw

gen/src/gleam@iterator.erl

-module(gleam@iterator).
-compile(no_auto_import).
-export([unfold/2, repeatedly/1, repeat/1, from_list/1, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, append/2, flatten/1, flat_map/2, filter/2, cycle/1, range/2, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2]).
-export_type([action/1, iterator/1, step/2]).
-type action(AYJ) :: stop | {continue, AYJ, fun(() -> action(AYJ))}.
-opaque iterator(AYK) :: {iterator, fun(() -> action(AYK))}.
-type step(AYL, AYM) :: {next, AYL, AYM} | done.
-spec do_unfold(AYP, fun((AYP) -> step(AYQ, AYP))) -> fun(() -> action(AYQ)).
do_unfold(Initial, F) ->
fun() -> case F(Initial) of
{next, X, Acc} ->
{continue, X, do_unfold(Acc, F)};
done ->
stop
end end.
-spec unfold(AYU, fun((AYU) -> step(AYV, AYU))) -> iterator(AYV).
unfold(Initial, F) ->
{iterator, do_unfold(Initial, F)}.
-spec repeatedly(fun(() -> AYZ)) -> iterator(AYZ).
repeatedly(F) ->
unfold(nil, fun(_) -> {next, F(), nil} end).
-spec repeat(AZB) -> iterator(AZB).
repeat(X) ->
repeatedly(fun() -> X end).
-spec from_list(list(AZD)) -> iterator(AZD).
from_list(List) ->
Yield = fun(Acc) -> case Acc of
[] ->
done;
[Head | Tail] ->
{next, Head, Tail}
end end,
unfold(List, Yield).
-spec do_fold(fun(() -> action(AZG)), AZI, fun((AZG, AZI) -> AZI)) -> AZI.
do_fold(Continuation, Initial, F) ->
case Continuation() of
{continue, Element, Iterator} ->
do_fold(Iterator, F(Element, Initial), F);
stop ->
Initial
end.
-spec fold(iterator(AZJ), AZL, fun((AZJ, AZL) -> AZL)) -> AZL.
fold(Iterator, Initial, F) ->
do_fold(erlang:element(2, Iterator), Initial, F).
-spec run(iterator(any())) -> nil.
run(Iterator) ->
fold(Iterator, nil, fun(_, _) -> nil end).
-spec to_list(iterator(AZO)) -> list(AZO).
to_list(Iterator) ->
gleam@list:reverse(fold(Iterator, [], fun(E, Acc) -> [E | Acc] end)).
-spec step(iterator(AZR)) -> step(AZR, iterator(AZR)).
step(Iterator) ->
case (erlang:element(2, Iterator))() of
stop ->
done;
{continue, E, A} ->
{next, E, {iterator, A}}
end.
-spec do_take(fun(() -> action(AZW)), integer(), list(AZW)) -> list(AZW).
do_take(Continuation, Desired, Acc) ->
case Desired > 0 of
true ->
case Continuation() of
{continue, Element, Iterator} ->
do_take(Iterator, Desired - 1, [Element | Acc]);
stop ->
gleam@list:reverse(Acc)
end;
false ->
gleam@list:reverse(Acc)
end.
-spec take(iterator(BAA), integer()) -> list(BAA).
take(Iterator, Desired) ->
do_take(erlang:element(2, Iterator), Desired, []).
-spec do_drop(fun(() -> action(BAD)), integer()) -> fun(() -> action(BAD)).
do_drop(Continuation, Desired) ->
case Desired > 0 of
true ->
case Continuation() of
{continue, _, Iterator} ->
do_drop(Iterator, Desired - 1);
stop ->
fun() -> stop end
end;
false ->
Continuation
end.
-spec drop(iterator(BAG), integer()) -> iterator(BAG).
drop(Iterator, Desired) ->
{iterator, do_drop(erlang:element(2, Iterator), Desired)}.
-spec do_map(fun(() -> action(BAJ)), fun((BAJ) -> BAL)) -> fun(() -> action(BAL)).
do_map(Continuation, F) ->
fun() -> case Continuation() of
{continue, E, Continuation@1} ->
{continue, F(E), do_map(Continuation@1, F)};
stop ->
stop
end end.
-spec map(iterator(BAN), fun((BAN) -> BAP)) -> iterator(BAP).
map(Iterator, F) ->
{iterator, do_map(erlang:element(2, Iterator), F)}.
-spec do_append(fun(() -> action(BAR)), fun(() -> action(BAR))) -> fun(() -> action(BAR)).
do_append(First, Second) ->
fun() -> case First() of
{continue, E, First@1} ->
{continue, E, do_append(First@1, Second)};
stop ->
Second()
end end.
-spec append(iterator(BAV), iterator(BAV)) -> iterator(BAV).
append(First, Second) ->
{iterator, do_append(erlang:element(2, First), erlang:element(2, Second))}.
-spec do_flatten(fun(() -> action(iterator(BAZ)))) -> fun(() -> action(BAZ)).
do_flatten(Continuation) ->
fun() -> case Continuation() of
{continue, E, Continuation@1} ->
(do_append(erlang:element(2, E), do_flatten(Continuation@1)))();
stop ->
stop
end end.
-spec flatten(iterator(iterator(BBD))) -> iterator(BBD).
flatten(Iterator) ->
{iterator, do_flatten(erlang:element(2, Iterator))}.
-spec flat_map(iterator(BBH), fun((BBH) -> iterator(BBJ))) -> iterator(BBJ).
flat_map(Iterator, F) ->
flatten(map(Iterator, F)).
-spec do_filter(fun(() -> action(BBM)), fun((BBM) -> boolean())) -> fun(() -> action(BBM)).
do_filter(Continuation, Predicate) ->
fun() -> case Continuation() of
{continue, E, Iterator} ->
case Predicate(E) of
true ->
{continue, E, do_filter(Iterator, Predicate)};
false ->
(do_filter(Iterator, Predicate))()
end;
stop ->
stop
end end.
-spec filter(iterator(BBP), fun((BBP) -> boolean())) -> iterator(BBP).
filter(Iterator, Predicate) ->
{iterator, do_filter(erlang:element(2, Iterator), Predicate)}.
-spec do_cycle(fun(() -> action(BBS)), fun(() -> action(BBS))) -> fun(() -> action(BBS)).
do_cycle(Next, Reset) ->
fun() -> case Next() of
{continue, E, Iterator} ->
{continue, E, do_cycle(Iterator, Reset)};
stop ->
(do_cycle(Reset, Reset))()
end end.
-spec cycle(iterator(BBW)) -> iterator(BBW).
cycle(Iterator) ->
{iterator,
do_cycle(erlang:element(2, Iterator), erlang:element(2, Iterator))}.
-spec do_range(integer(), integer(), integer()) -> fun(() -> action(integer())).
do_range(Current, Limit, Inc) ->
case Current =:= Limit of
true ->
fun() -> stop end;
false ->
fun() ->
{continue, Current, do_range(Current + Inc, Limit, Inc)}
end
end.
-spec range(integer(), integer()) -> iterator(integer()).
range(Start, Stop) ->
{iterator, do_range(Start, Stop, case Start < Stop of
true ->
1;
false ->
-1
end)}.
-spec find(iterator(BCE), fun((BCE) -> boolean())) -> {ok, BCE} | {error, nil}.
find(Haystack, Is_desired) ->
case (erlang:element(2, Haystack))() of
{continue, Element, Continuation} ->
case Is_desired(Element) of
true ->
{ok, Element};
false ->
find({iterator, Continuation}, Is_desired)
end;
stop ->
{error, nil}
end.
-spec do_index(fun(() -> action(BCI)), integer()) -> fun(() -> action({integer(),
BCI})).
do_index(Continuation, Next) ->
fun() -> case Continuation() of
{continue, E, Continuation@1} ->
{continue, {Next, E}, do_index(Continuation@1, Next + 1)};
stop ->
stop
end end.
-spec index(iterator(BCL)) -> iterator({integer(), BCL}).
index(Iterator) ->
{iterator, do_index(erlang:element(2, Iterator), 0)}.
-spec iterate(BCO, fun((BCO) -> BCO)) -> iterator(BCO).
iterate(Initial, F) ->
unfold(Initial, fun(Element) -> {next, Element, F(Element)} end).
-spec do_take_while(fun(() -> action(BCQ)), fun((BCQ) -> boolean())) -> fun(() -> action(BCQ)).
do_take_while(Continuation, Predicate) ->
fun() -> case Continuation() of
stop ->
stop;
{continue, E, Next} ->
case Predicate(E) of
false ->
stop;
true ->
{continue, E, do_take_while(Next, Predicate)}
end
end end.
-spec do_scan(fun(() -> action(BCT)), BCV, fun((BCT, BCV) -> BCV)) -> fun(() -> action(BCV)).
do_scan(Continuation, Accumulator, F) ->
fun() -> case Continuation() of
{continue, El, Next} ->
Accumulated = F(El, Accumulator),
{continue, Accumulated, do_scan(Next, Accumulated, F)};
stop ->
stop
end end.
-spec do_zip(fun(() -> action(BCX)), fun(() -> action(BCZ))) -> fun(() -> action({BCX,
BCZ})).
do_zip(Left, Right) ->
fun() -> case Left() of
stop ->
stop;
{continue, El_left, Next_left} ->
case Right() of
stop ->
stop;
{continue, El_right, Next_right} ->
{continue,
{El_left, El_right},
do_zip(Next_left, Next_right)}
end
end end.
-spec take_while(iterator(BDC), fun((BDC) -> boolean())) -> iterator(BDC).
take_while(Iterator, Predicate) ->
{iterator, do_take_while(erlang:element(2, Iterator), Predicate)}.
-spec do_drop_while(fun(() -> action(BDF)), fun((BDF) -> boolean())) -> action(BDF).
do_drop_while(Continuation, Predicate) ->
case Continuation() of
stop ->
stop;
{continue, E, Next} ->
case Predicate(E) of
false ->
{continue, E, Next};
true ->
do_drop_while(Next, Predicate)
end
end.
-spec drop_while(iterator(BDI), fun((BDI) -> boolean())) -> iterator(BDI).
drop_while(Iterator, Predicate) ->
{iterator,
fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end}.
-spec scan(iterator(BDL), BDN, fun((BDL, BDN) -> BDN)) -> iterator(BDN).
scan(Iterator, Initial, F) ->
{iterator, do_scan(erlang:element(2, Iterator), Initial, F)}.
-spec zip(iterator(BDP), iterator(BDR)) -> iterator({BDP, BDR}).
zip(Left, Right) ->
{iterator, do_zip(erlang:element(2, Left), erlang:element(2, Right))}.