Current section
Files
Jump to
Current section
Files
src/gens@lazy.erl
-module(gens@lazy).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/gens/lazy.gleam").
-export([new/0, take/2, map/2, filter/2, drop/2, zip/2, list_zip/2, alternative/0]).
-export_type([lazy_list/1, lazy_list_f/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC("================== Lazy List ==================\n").
-opaque lazy_list(HPE) :: {lazy_list,
integer(),
fun((integer()) -> HPE),
fun((integer()) -> boolean())}.
-type lazy_list_f() :: any().
-file("src/gens/lazy.gleam", 16).
?DOC(
" Default LazyList for the list of `natural numbers` [0..]\n"
" ```gleam\n"
" new() |> take(5)\n"
" // -> [0, 1, 2, 3, 4]\n"
" ```\n"
).
-spec new() -> lazy_list(integer()).
new() ->
{lazy_list, 0, fun(X) -> X end, fun(_) -> true end}.
-file("src/gens/lazy.gleam", 21).
?DOC(" `Tail recursive` function for **take**\n").
-spec take_acc(
integer(),
integer(),
integer(),
fun((integer()) -> HPG),
fun((integer()) -> boolean()),
list(HPG)
) -> list(HPG).
take_acc(Index, Step, Total, Fmap, Filt, Acc) ->
case Step < Total of
false ->
_pipe = Acc,
lists:reverse(_pipe);
true ->
case Filt(Index) of
false ->
take_acc(Index + 1, Step, Total, Fmap, Filt, Acc);
true ->
case Step >= 0 of
false ->
take_acc(
Index + 1,
Step + 1,
Total,
Fmap,
Filt,
Acc
);
true ->
take_acc(
Index + 1,
Step + 1,
Total,
Fmap,
Filt,
[Fmap(Index) | Acc]
)
end
end
end.
-file("src/gens/lazy.gleam", 52).
?DOC(
" **Takes** a `finite` number of elements from a LazyList\n"
" ```gleam\n"
" take(new(), 5)\n"
" // -> [0, 1, 2, 3, 4]\n"
" ```\n"
).
-spec take(lazy_list(HPJ), integer()) -> list(HPJ).
take(Ga, N) ->
case Ga of
{lazy_list, Index, Amap, Afilt} ->
take_acc(Index, 0, N, Amap, Afilt, [])
end.
-file("src/gens/lazy.gleam", 66).
?DOC(
" **Maps** each element of the generated list\n"
" ```gleam\n"
" new()\n"
" |> map(fn(x) { x + 3 })\n"
" |> map(int.to_string)\n"
" |> take(5)\n"
" // -> [\"3\", \"4\", \"5\", \"6\", \"7\"]\n"
" ```\n"
).
-spec map(lazy_list(HPM), fun((HPM) -> HPO)) -> lazy_list(HPO).
map(Ga, F) ->
case Ga of
{lazy_list, Index, Amap, Afilt} ->
{lazy_list, Index, fun(N) -> F(Amap(N)) end, Afilt}
end.
-file("src/gens/lazy.gleam", 80).
?DOC(
" **Filters** elements from the generated list\n"
" ```gleam\n"
" new()\n"
" |> filter(fn(x) { x % 2 == 0 })\n"
" |> filter(fn(x) { x != 4 })\n"
" |> take(5)\n"
" // -> [0, 2, 6, 8, 10]\n"
" ```\n"
).
-spec filter(lazy_list(HPQ), fun((HPQ) -> boolean())) -> lazy_list(HPQ).
filter(Ga, F) ->
case Ga of
{lazy_list, Index, Amap, Afilt} ->
{lazy_list, Index, Amap, fun(N) -> Afilt(N) andalso F(Amap(N)) end}
end.
-file("src/gens/lazy.gleam", 88).
-spec advance(integer(), integer(), fun((integer()) -> boolean())) -> integer().
advance(Index, Steps, Filt) ->
case Steps >= 0 of
false ->
Index - 1;
true ->
case Filt(Index) of
false ->
advance(Index + 1, Steps, Filt);
true ->
advance(Index + 1, Steps - 1, Filt)
end
end.
-file("src/gens/lazy.gleam", 114).
?DOC(
" **Drops** the first n elements of a LazyList\n"
" ```gleam\n"
" new() // [0, 1, 2, 3, 4..]\n"
" |> drop(4) // [4, 5, 6, 7..]\n"
" |> filter(int.is_even) // [4, 6, 8..]\n"
" |> take(5)\n"
" // -> [4, 6, 8, 10, 12]\n"
" ```\n"
" ```gleam\n"
" new() // [0, 1, 2, 3, 4..]\n"
" |> filter(int.is_even) // [0, 2, 4, 6, 8..]\n"
" |> drop(4) // [8, 10, 12..]\n"
" |> take(5)\n"
" // -> [8, 10, 12, 14, 16]\n"
" ```\n"
).
-spec drop(lazy_list(HPT), integer()) -> lazy_list(HPT).
drop(Ga, Steps) ->
case Steps >= 0 of
false ->
Ga;
true ->
case Ga of
{lazy_list, Index, Amap, Afilt} ->
{lazy_list, advance(Index, Steps, Afilt), Amap, Afilt}
end
end.
-file("src/gens/lazy.gleam", 136).
?DOC(
" **Zips** two LazyLists into one\n"
" - The resulting index is the maximum of the two takes \n"
" - The filters get combined\n"
" - For separate indexes, do `list.zip(take(g1, n), take(g2, n))`\n"
" ```gleam\n"
" let g1 = new() |> map(fn(x) { x + 2 })\n"
" let g2 = new() |> filter(int.is_even)\n"
" zip(g1, g2)\n"
" |> take(3)\n"
" // -> [#(2, 0), #(4, 2), #(6, 4)]\n"
" ```\n"
).
-spec zip(lazy_list(HPW), lazy_list(HPY)) -> lazy_list({HPW, HPY}).
zip(Ga, Gb) ->
{lazy_list, Aindex, Amap, Afilt} = Ga,
{lazy_list, Bindex, Bmap, Bfilt} = Gb,
{lazy_list,
gleam@int:max(Aindex, Bindex),
fun(N) -> {Amap(N), Bmap(N)} end,
fun(N@1) -> Afilt(N@1) andalso Bfilt(N@1) end}.
-file("src/gens/lazy.gleam", 150).
?DOC(
" **Zips** a list with an infinite list\n"
" ```gleam\n"
" [\"a\", \"b\", \"c\"] \n"
" |> list_zip(new())\n"
" // -> [#(\"a\", 0), #(\"b\", 1), #(\"c\", 2)]\n"
" ```\n"
).
-spec list_zip(list(HQB), lazy_list(HQD)) -> list({HQB, HQD}).
list_zip(La, Gb) ->
gleam@list:zip(La, take(Gb, erlang:length(La))).
-file("src/gens/lazy.gleam", 173).
?DOC(
" `Alternative` instance for `LazyList`\n"
" ```gleam\n"
" let odd_pears =\n"
" new()\n"
" |> filter(int.is_odd)\n"
" |> map(fn(x) { int.to_string(x) <> \" pears\" })\n"
" let triple_kiwis =\n"
" new()\n"
" |> drop(3)\n"
" |> filter(fn(x) { x % 3 == 0 })\n"
" |> map(fn(x) { int.to_string(x) <> \" kiwis\" })\n"
" // Combining the two lists\n"
" let fruits = alternative().or(odd_pears, triple_kiwis)\n"
" take(fruits, 8)\n"
" // -> [\"3 pears\", \"5 pears\", \"6 kiwis\", \"7 pears\", \"9 pears\", \"11 pears\", \"12 kiwis\", \"13 pears\"]\n"
" ```\n"
).
-spec alternative() -> cat@alternative:alternative(lazy_list_f(), lazy_list(any())).
alternative() ->
{alternative, {lazy_list, 0, fun(_) -> erlang:error(#{gleam_error => panic,
message => <<"`panic` expression evaluated."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gens/lazy"/utf8>>,
function => <<"alternative"/utf8>>,
line => 175}) end, fun(_) -> false end}, fun(L1, L2) ->
{lazy_list,
gleam@int:max(erlang:element(2, L1), erlang:element(2, L2)),
fun(N) -> case (erlang:element(4, L1))(N) of
true ->
(erlang:element(3, L1))(N);
false ->
(erlang:element(3, L2))(N)
end end,
fun(X) ->
(erlang:element(4, L1))(X) orelse (erlang:element(4, L2))(X)
end}
end}.