// ets_tracing: off import * as ChunkCollect from "../Collections/Immutable/Chunk/api/collect.js" import * as Chunk from "../Collections/Immutable/Chunk/core.js" import { identity } from "../Function/index.js" import type * as O from "../Option/index.js" import type { Sync } from "./core.js" import * as core from "./core.js" /** * Applies the function `f` to each element of the `Iterable` and * returns the results in a new `readonly B[]`. * * For a parallel version of this method, see `forEachPar`. * If you do not need the results, see `forEachUnit` for a more efficient implementation. */ export function forEach_( as: Iterable, f: (a: A) => Sync ): Sync> { return core.suspend(() => { const acc: B[] = [] return core.map_( forEachUnit_(as, (a) => core.map_(f(a), (b) => { acc.push(b) }) ), () => Chunk.from(acc) ) }) } /** * Applies the function `f` to each element of the `Iterable` and * returns the results in a new `readonly B[]`. * * For a parallel version of this method, see `forEachPar`. * If you do not need the results, see `forEachUnit` for a more efficient implementation. * * @ets_data_first forEach_ */ export function forEach(f: (a: A) => Sync) { return (as: Iterable) => forEach_(as, f) } function forEachUnitLoop( iterator: Iterator, f: (a: A) => Sync ): Sync { const next = iterator.next() return next.done ? core.unit : core.chain_(f(next.value), () => forEachUnitLoop(iterator, f)) } /** * Applies the function `f` to each element of the `Iterable` and runs * produced Syncs sequentially. * * Equivalent to `asUnit(forEach(as, f))`, but without the cost of building * the list of results. */ export function forEachUnit_( as: Iterable, f: (a: A) => Sync, __trace?: string ): Sync { return core.suspend(() => forEachUnitLoop(as[Symbol.iterator](), f)) } /** * Applies the function `f` to each element of the `Iterable` and runs * produced Syncs sequentially. * * Equivalent to `asUnit(forEach(as, f))`, but without the cost of building * the list of results. * * @ets_data_first forEachUnit_ */ export function forEachUnit( f: (a: A) => Sync, __trace?: string ): (as: Iterable) => Sync { return (as) => forEachUnit_(as, f) } /** * Evaluate each Sync in the structure from left to right, and collect the * results. For a parallel version, see `collectAllPar`. */ export function collectAll(as: Iterable>) { return forEach_(as, identity) } /** * Evaluate each Sync in the structure from left to right, and discard the * results. For a parallel version, see `collectAllUnitPar`. */ export function collectAllUnit(as: Iterable>, __trace?: string) { return forEachUnit_(as, identity) } /** * Evaluate each Sync in the structure with `collectAll`, and collect * the results with given partial function. */ export function collectAllWith_( as: Iterable>, pf: (a: A) => O.Option, __trace?: string ): Sync> { return core.map_(collectAll(as), ChunkCollect.collect(pf)) } /** * Evaluate each Sync in the structure with `collectAll`, and collect * the results with given partial function. * * @ets_data_first collectAllWith_ */ export function collectAllWith(pf: (a: A) => O.Option) { return (as: Iterable>) => collectAllWith_(as, pf) }