import type { Curried } from '../../compositions/curry.js'; import { type Purried, purry } from '../../compositions/purry.js'; import { _isIterable } from '../../controls/_guards.js'; import type { Series, SyncSeries } from '../../controls/types.js'; function _syncReduce( input: SyncSeries, reducer: (accumulator: R | I, value: T) => R, initialValue: I, ): I | R { let returnValue: I | R = initialValue; for (const value of input) { returnValue = reducer(returnValue, value); } return returnValue; } async function _asyncReduce( input: Series, reducer: (accumulator: Awaited, value: Awaited) => R | Promise, initialValue: I | Promise, ): Promise | Awaited> { let returnValue: Awaited | Awaited = await initialValue; const awaited = await input; if (_isIterable(awaited)) { for (const value of awaited) { returnValue = await reducer(returnValue, await value); } } else { for await (const value of awaited) { returnValue = await reducer(returnValue, value); } } return returnValue; } export function reduceSync( ...args: Parameters> ): ReturnType>; export function reduceSync( ...args: Parameters>> ): ReturnType>>; export function reduceSync( ...args: Parameters>> ): ReturnType>> { return purry(_syncReduce)(...args); } export function reduceAsync( ...args: Parameters> ): ReturnType>; export function reduceAsync( ...args: Parameters>> ): ReturnType>>; export function reduceAsync( ...args: Parameters>> ): ReturnType>> { return purry(_asyncReduce)(...args); } /** Reduce elements into one accumulated value by the specified reducer. */ export namespace reduce { export const sync = reduceSync; export const async = reduceAsync; }