export interface Reduced { ["@@transducer/reduced"]: boolean; ["@@transducer/value"]: TResult; } export type Reducer = (result: TResult, input: TInput) => TResult; // Common case: Transducer = // Transformer => Transformer. export interface Transducer { (xf: Transformer): Transformer; ( xf: CompletingTransformer, ): CompletingTransformer; } export interface CompletingTransformer { // eslint-disable-next-line @typescript-eslint/no-invalid-void-type ["@@transducer/init"](): TResult | void; ["@@transducer/step"](result: TResult, input: TInput): TResult | Reduced; ["@@transducer/result"](result: TResult): TCompleteResult; } export type Transformer = CompletingTransformer; /** * Return a reduced value. Reduced values short circuit transduce. */ export function reduced(x: TResult): Reduced; /** * Check if a value is reduced. */ export function isReduced(x: any): boolean; /** * Function composition. Take N function and return their composition. */ // 2-4 Transducers export function comp(a: Transducer, b: Transducer): Transducer; export function comp(a: Transducer, b: Transducer, c: Transducer): Transducer; export function comp( a: Transducer, b: Transducer, c: Transducer, d: Transducer, ): Transducer; // N identical Transducers export function comp(...args: Array>): Transducer; // 2-4 arbitrary functions export function comp(b: (b: B) => C, a: (a: A) => B): (a: A) => C; export function comp(c: (c: C) => D, b: (b: B) => C, a: (a: A) => B): (a: A) => D; export function comp(d: (d: D) => E, c: (c: C) => D, b: (b: B) => C, a: (a: A) => B): (a: A) => E; // N identical functions export function comp(...args: Array<(a: A) => A>): A; // Falls back to (any => any) when argument types differ. export function comp(...args: Array<(x: any) => any>): (x: any) => any; /** * Take a predicate function and return its complement. */ export function complement(f: (x: T) => boolean): (x: T) => boolean; /** * Identity function. */ export function identity(arg: T): T; export class Map implements Transformer { constructor(f: (x: TInput) => TOutput, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * Mapping transducer constructor */ export function map(f: (x: TInput) => TOutput): Transducer; export class Filter implements Transformer { constructor(pred: (x: TInput) => boolean, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * Filtering transducer constructor */ export function filter(pred: (x: TInput) => boolean): Transducer; /** * Similar to filter except the predicate is used to * eliminate values. */ export function remove(pred: (x: TInput) => boolean): Transducer; export class Keep implements Transformer { constructor(f: (x: TInput) => any, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A keeping transducer. Keep inputs as long as the provided * function does not return null or undefined. */ export function keep(f: (x: TInput) => any): Transducer; export class KeepIndexed implements Transformer { constructor(f: (i: number, x: TInput) => any, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * Like keep but the provided function will be passed the * index as the fist argument. */ export function keepIndexed(f: (i: number, x: TInput) => any): Transducer; export class Take implements Transformer { constructor(n: number, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult | Reduced; ["@@transducer/result"](result: TResult): TResult; } /** * A take transducer constructor. Will take n values before * returning a reduced result. */ export function take(n: number): Transducer; export class TakeWhile implements Transformer { constructor(pred: (n: TInput) => boolean, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult | Reduced; ["@@transducer/result"](result: TResult): TResult; } /** * Like the take transducer except takes as long as the pred * return true for inputs. */ export function takeWhile(pred: (n: TInput) => boolean): Transducer; export class TakeNth implements Transformer { constructor(n: number, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A transducer that takes every Nth input */ export function takeNth(n: number): Transducer; export class Drop implements Transformer { constructor(n: number, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A dropping transducer constructor */ export function drop(n: number): Transducer; export class DropWhile implements Transformer { constructor(pred: (input: TInput) => boolean, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A dropping transducer that drop inputs as long as * pred is true. */ export function dropWhile(pred: (input: TInput) => boolean): Transducer; export class PartitionBy implements Transformer { constructor(f: (input: TInput) => any, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A partitioning transducer. Collects inputs into * arrays as long as predicate remains true for contiguous * inputs. */ export function partitionBy(f: (input: TInput) => any): Transducer; export class PartitionAll implements Transformer { constructor(n: number, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * A partitioning transducer. Collects inputs into * arrays of size N. */ export function partitionAll(n: number): Transducer; export class Completing implements CompletingTransformer { constructor(cf: (result: TResult) => TCompleteResult, xf: Transformer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TCompleteResult; } /** * A completing transducer constructor. Useful to provide cleanup * logic at the end of a reduction/transduction. */ export function completing( xf: Transformer | Reducer, cf: (result: TResult) => TCompleteResult, ): CompletingTransformer; export class Wrap implements Transformer { constructor(stepFn: Reducer); ["@@transducer/init"](): TResult; ["@@transducer/step"](result: TResult, input: TInput): TResult; ["@@transducer/result"](result: TResult): TResult; } /** * Take a two-arity reducing function where the first argument is the * accumluation and the second argument is the next input and convert * it into a transducer transformer object. */ export function wrap(stepFn: Reducer): Transformer; /** * Given a transformer return a concatenating transformer */ export function cat(xf: Transformer): Transformer>; /** * A mapping concatenating transformer */ export function mapcat(f: (arr: TInput) => Iterable): Transducer; /** * Given a transducer, a builder function, an initial value * and a iterable collection - returns the reduction. */ export function transduce( xf: Transducer, f: Reducer, init: TResult, coll: Iterable, ): TResult; export function transduce( xf: Transducer, f: CompletingTransformer, init: TResult, coll: Iterable, ): TCompleteResult; export function transduce( xf: Transducer, f: CompletingTransformer, coll: Iterable, ): TCompleteResult; // Overloads for object iteration. export function transduce( xf: Transducer<[string, TInput], TOutput>, f: Reducer, init: TResult, coll: { [key: string]: TInput }, ): TResult; export function transduce( xf: Transducer<[string, TInput], TOutput>, f: CompletingTransformer, init: TResult, coll: { [key: string]: TInput }, ): TCompleteResult; export function transduce( xf: Transducer<[string, TInput], TOutput>, f: CompletingTransformer, coll: { [key: string]: TInput }, ): TCompleteResult; /** * Given a transducer, an intial value and a * collection - returns the reduction. */ export function reduce( xf: Transformer | Reducer, init: TResult, coll: Iterable, ): TResult; export function reduce( xf: CompletingTransformer, init: TResult, coll: Iterable, ): TCompleteResult; // Overloads for object iteration. export function reduce( xf: Transformer | Reducer, init: TResult, coll: { [key: string]: TInput }, ): TResult; export function reduce( xf: CompletingTransformer, init: TResult, coll: { [key: string]: TInput }, ): TCompleteResult; /** * Reduce a value into the given empty value using a transducer. */ export function into( empty: TOutput[], xf: Transducer, coll: Iterable, ): TOutput[]; export function into( empty: string, xf: Transducer, coll: Iterable, ): string; export function into( empty: { [key: string]: TOutput }, xf: Transducer, coll: Iterable, ): { [key: string]: TOutput }; // Overloads for object iteration. export function into( empty: TOutput[], xf: Transducer<[string, TInput], TOutput>, coll: { [key: string]: TInput }, ): TOutput[]; export function into( empty: string, xf: Transducer<[string, TInput], string>, coll: { [key: string]: TInput }, ): string; export function into( empty: { [key: string]: TOutput }, xf: Transducer<[string, TInput], [string, TOutput]>, coll: { [key: string]: TInput }, ): { [key: string]: TOutput }; /** * Convert a transducer transformer object into a function so * that it can be used with existing reduce implementation i.e. native, * Underscore, lodash */ export function toFn( xf: Transducer, builder: Reducer | Transformer, ): Reducer; /** * A transformer which simply returns the first input. */ export function first(): Wrap; /** * Ensure that a value is reduced. If already reduced will not re-wrap. */ export function ensureReduced(x: TResult | Reduced): Reduced; /** * Ensure a value is not reduced. Unwraps if reduced. */ export function unreduced(x: TResult | Reduced): TResult; /** * Returns the value of a reduced result. */ export function deref(x: Reduced): TResult;