gossamer/async_yielder
A pull-based async iteration type implemented in pure Gleam. The
canonical type for iterating over Promise-yielding sources;
mirrors gleam_yielder.Yielder for async iteration.
Callback-taking operations come in paired sync (map, filter,
each, …) and async (map_async, filter_async, each_async, …)
twins; the _async twin accepts a Promise-returning callback.
Fallible operations should be expressed via Result inside the
promise, following gleam_javascript convention.
Types
A pull-based async iterator. Each pull returns a promise for the
next Step.
pub opaque type AsyncYielder(a)
One step of iteration: either the next element paired with an
accumulator to feed into the next step, or Done to halt.
When returned from step, accumulator is the next
AsyncYielder. When passed to unfold,
accumulator is the user’s state.
pub type Step(element, accumulator) {
Next(element: element, accumulator: accumulator)
Done
}
Constructors
-
Next(element: element, accumulator: accumulator) -
Done
Values
pub fn all(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> Bool,
) -> promise.Promise(Bool)
Returns True if predicate returns True for every value of
yielder. Stops at the first non-match.
pub fn all_async(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> promise.Promise(Bool),
) -> promise.Promise(Bool)
Like all but predicate returns a Promise. Each call
is awaited before the next.
pub fn any(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> Bool,
) -> promise.Promise(Bool)
Returns True if predicate returns True for any value of
yielder. Stops at the first match.
pub fn any_async(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> promise.Promise(Bool),
) -> promise.Promise(Bool)
Like any but predicate returns a Promise. Each call
is awaited before the next.
pub fn append(
to first: AsyncYielder(a),
suffix second: AsyncYielder(a),
) -> AsyncYielder(a)
Concatenates two yielders: yields all of first’s values, then all
of second’s.
pub fn at(
in yielder: AsyncYielder(a),
get index: Int,
) -> promise.Promise(Result(a, Nil))
Returns the value at zero-based index, or Error(Nil) if the
yielder has fewer than index + 1 values.
pub fn chunk(
over yielder: AsyncYielder(a),
by fun: fn(a) -> key,
) -> AsyncYielder(List(a))
Groups consecutive values of yielder that share the same key
(computed by fun) into lists.
pub fn chunk_async(
over yielder: AsyncYielder(a),
by fun: fn(a) -> promise.Promise(key),
) -> AsyncYielder(List(a))
Like chunk but fun returns a Promise. Each call is
awaited before the next.
pub fn concat(yielders: List(AsyncYielder(a))) -> AsyncYielder(a)
Concatenates a list of yielders into a single yielder.
pub fn cycle(yielder: AsyncYielder(a)) -> AsyncYielder(a)
Repeats yielder infinitely, restarting from the beginning each
round. Pair with take to bound it. Cycling an empty
yielder yields nothing and never halts, so don’t fully drain it.
pub fn drop(
from yielder: AsyncYielder(a),
up_to desired: Int,
) -> AsyncYielder(a)
Skips the first desired values of yielder, then yields the
rest. If desired is non-positive, yields all values.
pub fn drop_while(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> Bool,
) -> AsyncYielder(a)
Skips values from yielder while predicate returns True, then
yields the rest starting from the first value for which it returns
False.
pub fn drop_while_async(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> promise.Promise(Bool),
) -> AsyncYielder(a)
Like drop_while but predicate returns a
Promise. Each call is awaited before the next.
pub fn each(
over yielder: AsyncYielder(a),
with fun: fn(a) -> b,
) -> promise.Promise(Nil)
Drains the yielder, calling fun on each yielded value.
pub fn each_async(
over yielder: AsyncYielder(a),
with fun: fn(a) -> promise.Promise(b),
) -> promise.Promise(Nil)
Like each but fun returns a Promise. Each call is
awaited before the next.
pub fn filter(
yielder: AsyncYielder(a),
keeping predicate: fn(a) -> Bool,
) -> AsyncYielder(a)
Yields only values from yielder for which predicate returns
True.
pub fn filter_async(
yielder: AsyncYielder(a),
keeping predicate: fn(a) -> promise.Promise(Bool),
) -> AsyncYielder(a)
Like filter but predicate returns a Promise. Each
call is awaited before the next.
pub fn filter_map(
yielder: AsyncYielder(a),
keeping_with fun: fn(a) -> Result(b, c),
) -> AsyncYielder(b)
Applies fun to each value of yielder, keeping the Ok results
and dropping the Errors.
pub fn filter_map_async(
yielder: AsyncYielder(a),
keeping_with fun: fn(a) -> promise.Promise(Result(b, c)),
) -> AsyncYielder(b)
Like filter_map but fun returns a Promise.
Each call is awaited before the next.
pub fn find(
in haystack: AsyncYielder(a),
one_that is_desired: fn(a) -> Bool,
) -> promise.Promise(Result(a, Nil))
Returns the first value of haystack for which is_desired
returns True, or Error(Nil) if none match.
pub fn find_async(
in haystack: AsyncYielder(a),
one_that is_desired: fn(a) -> promise.Promise(Bool),
) -> promise.Promise(Result(a, Nil))
Like find but is_desired returns a Promise. Each
call is awaited before the next.
pub fn find_map(
in haystack: AsyncYielder(a),
one_that is_desired: fn(a) -> Result(b, c),
) -> promise.Promise(Result(b, Nil))
Returns the first Ok result of applying is_desired to values
of haystack, or Error(Nil) if every call returns Error.
pub fn find_map_async(
in haystack: AsyncYielder(a),
one_that is_desired: fn(a) -> promise.Promise(Result(b, c)),
) -> promise.Promise(Result(b, Nil))
Like find_map but is_desired returns a Promise.
Each call is awaited before the next.
pub fn first(
from yielder: AsyncYielder(a),
) -> promise.Promise(Result(a, Nil))
Returns the first value of the yielder, or Error(Nil) if it’s
empty.
pub fn flat_map(
over yielder: AsyncYielder(a),
with fun: fn(a) -> AsyncYielder(b),
) -> AsyncYielder(b)
Applies fun to each value of yielder and flattens the resulting
yielders.
pub fn flat_map_async(
over yielder: AsyncYielder(a),
with fun: fn(a) -> promise.Promise(AsyncYielder(b)),
) -> AsyncYielder(b)
Like flat_map but fun returns a Promise. Each
call is awaited before the next.
pub fn flatten(
yielder: AsyncYielder(AsyncYielder(a)),
) -> AsyncYielder(a)
Flattens a yielder of yielders into a single yielder, yielding all of each inner yielder’s values in order.
pub fn fold(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> acc,
) -> promise.Promise(acc)
Reduces the yielder to a single value by repeatedly applying
fun to an accumulator and each yielded value, starting with
initial.
pub fn fold_async(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> promise.Promise(acc),
) -> promise.Promise(acc)
Like fold but fun returns a Promise. Each call is
awaited before the next.
pub fn fold_until(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> list.ContinueOrStop(acc),
) -> promise.Promise(acc)
Like fold but fun can stop the iteration early by
returning list.Stop(acc); list.Continue(acc) proceeds with the
new accumulator.
pub fn fold_until_async(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> promise.Promise(
list.ContinueOrStop(acc),
),
) -> promise.Promise(acc)
Like fold_until but fun returns a Promise.
Each call is awaited before the next.
pub fn from_list(list: List(a)) -> AsyncYielder(a)
Creates an async yielder from a Gleam list. Each value resolves synchronously.
pub fn group(
in yielder: AsyncYielder(a),
by key: fn(a) -> key,
) -> promise.Promise(dict.Dict(key, List(a)))
Drains the yielder and groups its values into a Dict
keyed by key(value), with each key’s values in the order they
were yielded.
pub fn group_async(
in yielder: AsyncYielder(a),
by key: fn(a) -> promise.Promise(key),
) -> promise.Promise(dict.Dict(key, List(a)))
Like group but key returns a Promise. Each call is
awaited before the next.
pub fn index(
over yielder: AsyncYielder(a),
) -> AsyncYielder(#(a, Int))
Yields each value of yielder paired with its zero-based index.
pub fn interleave(
left: AsyncYielder(a),
with right: AsyncYielder(a),
) -> AsyncYielder(a)
Alternates yielding values from left and right. When one side
is exhausted, continues with whatever remains of the other.
pub fn intersperse(
over yielder: AsyncYielder(a),
with elem: a,
) -> AsyncYielder(a)
Yields each value of yielder with elem inserted between
consecutive values. No trailing elem.
pub fn iterate(
from initial: a,
with fun: fn(a) -> a,
) -> AsyncYielder(a)
Constructs an async yielder by repeatedly applying fun to the
previous value, starting from initial. The yielder is infinite.
pub fn iterate_async(
from initial: a,
with fun: fn(a) -> promise.Promise(a),
) -> AsyncYielder(a)
Like iterate but fun returns a Promise. Each call
is awaited before the next.
pub fn last(
yielder: AsyncYielder(a),
) -> promise.Promise(Result(a, Nil))
Returns the last value of the yielder, or Error(Nil) if it’s
empty. Drains the yielder.
pub fn length(
over yielder: AsyncYielder(a),
) -> promise.Promise(Int)
Counts the elements in the yielder by draining it.
pub fn map(
over yielder: AsyncYielder(a),
with fun: fn(a) -> b,
) -> AsyncYielder(b)
Applies fun to each value of yielder as it’s pulled.
pub fn map2(
yielder1: AsyncYielder(a),
yielder2: AsyncYielder(b),
with fun: fn(a, b) -> c,
) -> AsyncYielder(c)
Yields the result of fun(left_value, right_value) for each
corresponding pair from yielder1 and yielder2, stopping when
either runs out.
pub fn map2_async(
yielder1: AsyncYielder(a),
yielder2: AsyncYielder(b),
with fun: fn(a, b) -> promise.Promise(c),
) -> AsyncYielder(c)
Like map2 but fun returns a Promise. Each call is
awaited before the next.
pub fn map_async(
over yielder: AsyncYielder(a),
with fun: fn(a) -> promise.Promise(b),
) -> AsyncYielder(b)
Like map but fun returns a Promise. Each call is
awaited before the next.
pub fn once(fun: fn() -> a) -> AsyncYielder(a)
An async yielder that yields the result of fun(), then stops.
pub fn once_async(
fun: fn() -> promise.Promise(a),
) -> AsyncYielder(a)
Like once but fun returns a Promise. The promise is
awaited when the yielder is first pulled.
pub fn prepend(
yielder: AsyncYielder(a),
element: a,
) -> AsyncYielder(a)
Adds element to the front of yielder.
pub fn range(from start: Int, to stop: Int) -> AsyncYielder(Int)
An async yielder of integers from start up to (or down to) stop,
inclusive on both ends.
pub fn reduce(
over yielder: AsyncYielder(a),
with fun: fn(a, a) -> a,
) -> promise.Promise(Result(a, Nil))
Reduces the yielder to a single value by repeatedly applying
fun to two values, starting with the first two. Returns
Error(Nil) if the yielder is empty.
pub fn reduce_async(
over yielder: AsyncYielder(a),
with fun: fn(a, a) -> promise.Promise(a),
) -> promise.Promise(Result(a, Nil))
Like reduce but fun returns a Promise. Each call
is awaited before the next.
pub fn repeatedly(fun: fn() -> a) -> AsyncYielder(a)
An async yielder that yields fun() infinitely.
pub fn repeatedly_async(
fun: fn() -> promise.Promise(a),
) -> AsyncYielder(a)
Like repeatedly but fun returns a Promise.
Each call is awaited before the next.
pub fn run(yielder: AsyncYielder(a)) -> promise.Promise(Nil)
Drains the yielder, discarding all values.
pub fn scan(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> acc,
) -> AsyncYielder(acc)
Yields the running accumulation of fun(acc, value) starting from
initial. Empty source yields nothing (the initial value is not
emitted alone).
pub fn scan_async(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> promise.Promise(acc),
) -> AsyncYielder(acc)
Like scan but fun returns a Promise. Each call is
awaited before the next.
pub fn single(elem: a) -> AsyncYielder(a)
An async yielder that yields exactly elem, then stops.
pub fn sized_chunk(
over yielder: AsyncYielder(a),
into count: Int,
) -> AsyncYielder(List(a))
Splits yielder into fixed-size lists. The final list may be
shorter than count. For any count less than 1 this function
behaves as if it was set to 1.
pub fn step(
yielder: AsyncYielder(a),
) -> promise.Promise(Step(a, AsyncYielder(a)))
Pulls the next Step from yielder.
pub fn take(
from yielder: AsyncYielder(a),
up_to desired: Int,
) -> AsyncYielder(a)
Yields the first desired values of yielder, then stops. If
desired is non-positive, yields nothing.
pub fn take_while(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> Bool,
) -> AsyncYielder(a)
Yields values from yielder while predicate returns True, then
stops at the first value for which it returns False.
pub fn take_while_async(
in yielder: AsyncYielder(a),
satisfying predicate: fn(a) -> promise.Promise(Bool),
) -> AsyncYielder(a)
Like take_while but predicate returns a
Promise. Each call is awaited before the next.
pub fn to_list(
yielder: AsyncYielder(a),
) -> promise.Promise(List(a))
Drains the yielder, collecting all yielded values into a list.
pub fn transform(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> Step(b, acc),
) -> AsyncYielder(b)
Stateful map: threads initial through fun(acc, value), which
returns the next Step. Next(emit, new_acc) yields
emit and continues with new_acc; Done ends the yielder early.
pub fn transform_async(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> promise.Promise(Step(b, acc)),
) -> AsyncYielder(b)
Like transform but fun returns a Promise. Each
call is awaited before the next.
pub fn try_fold(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> Result(acc, err),
) -> promise.Promise(Result(acc, err))
Like fold but fun returns a Result; an Error
halts iteration and surfaces as the overall Error.
pub fn try_fold_async(
over yielder: AsyncYielder(a),
from initial: acc,
with fun: fn(acc, a) -> promise.Promise(Result(acc, err)),
) -> promise.Promise(Result(acc, err))
Like try_fold but fun returns a Promise. Each
call is awaited before the next.
pub fn unfold(
from initial: acc,
with fun: fn(acc) -> Step(a, acc),
) -> AsyncYielder(a)
Constructs an async yielder by repeatedly calling fun with an
accumulator, starting with initial. Each Next(element, accumulator) yields the element and feeds the new accumulator into
the next call; Done stops the yielder.
pub fn unfold_async(
from initial: acc,
with fun: fn(acc) -> promise.Promise(Step(a, acc)),
) -> AsyncYielder(a)
Like unfold but fun returns a Promise. Each call is
awaited before the next.
pub fn yield(
element: a,
next: fn() -> AsyncYielder(a),
) -> AsyncYielder(a)
Yields element followed by whatever next() produces. next()
is only called when the yielder is pulled past element.
pub fn yield_async(
element: a,
next: fn() -> promise.Promise(AsyncYielder(a)),
) -> AsyncYielder(a)
Like yield but next returns a Promise. The promise
is awaited when the yielder is pulled past element.
pub fn zip(
left: AsyncYielder(a),
right: AsyncYielder(b),
) -> AsyncYielder(#(a, b))
Yields pairs of corresponding elements from left and right,
stopping when either runs out.