import { Option } from '@onekuma/option';

type ForEach<T> = (consumer: (value: T) => void) => boolean;
declare abstract class BaseSeq<T = unknown> {
}
declare class Seq<T = unknown> extends BaseSeq<T> {
    protected forEach: ForEach<T>;
    protected done: boolean;
    constructor(forEach: ForEach<T>, done?: boolean);
    static of<R>(...args: R[]): Seq<R>;
    static from<R>(arr: R[] | IterableIterator<R>): Seq<R>;
    static range(n: number): Seq<number>;
    static range(l: number, r: number): Seq<number>;
    map<R>(fn: (elem: T) => R): Seq<R>;
    enumerate(): Seq<[number, T]>;
    filter(predicate: (elem: T) => boolean): Seq<T>;
    filterDef(): Seq<NonNullable<T>>;
    catch<E extends Error>(handler?: (error: E) => void): Seq<T>;
    first(): Option<T>;
    last(): Option<T>;
    take(count: number): Seq<T>;
    drop(count: number): Seq<T>;
    static chain<T>(...args: Seq<T>[]): Seq<T>;
    concat(...args: Seq<T>[]): Seq<T>;
    append(...args: T[]): Seq<T>;
    [Symbol.iterator](): Generator<T, void, unknown>;
    async(): AsyncSeq<T>;
    reduce(reducer: (acc: T, elem: T) => T): Option<T>;
    fold<R>(initial: R, reducer: (acc: R, elem: T) => R): R;
    parallel<R>(fn: (elem: T) => Promise<R>): Promise<R[]>;
    toArray(): T[];
    private close;
}
type AsyncForEach<T> = (consumer: (value: T) => Promise<void>) => Promise<boolean>;
declare class AsyncSeq<T = unknown> extends BaseSeq<T> {
    protected forEach: AsyncForEach<T>;
    protected done: boolean;
    constructor(forEach: AsyncForEach<T>, done?: boolean);
    static of<R>(...args: R[]): AsyncSeq<R>;
    static from<R>(arr: R[] | IterableIterator<R>): AsyncSeq<R>;
    map<R>(fn: (elem: T) => Promise<R>): AsyncSeq<R>;
    filter(fn: (elem: T) => Promise<boolean>): AsyncSeq<T>;
    toArray(): Promise<T[]>;
    private close;
}
declare class SeqError extends Error {
    constructor();
}
declare function range(n: number | any[]): Seq<number>;
declare function range(l: number, r: number): Seq<number>;
declare function range(l: number, r: number, step: number): Seq<number>;

export { AsyncSeq, Seq, SeqError, range };
