/**
 * None represents an optional value that is not present
 */
declare class NoneImpl implements Option<never> {
    get isSome(): boolean;
    get isNone(): boolean;
    get(): never;
    getOrElse<B>(defaultValue: B): B;
    getOrCall<B>(f: () => B): B;
    getOrThrow(error: Error): never;
    map<B>(_f: (a: never) => B): Option<B>;
    mapOr<B>(defaultValue: B, _f: (a: never) => B): Option<B>;
    flatMap<B>(_f: (a: never) => Option<B>): Option<B>;
    orElse<B>(alternative: Option<B>): Option<B>;
    orCall<B>(f: () => Option<B>): Option<B>;
    filter(_predicate: (a: never) => boolean): Option<never>;
    forEach(_f: (a: never) => void): void;
    toArray(): never[];
    toEither<E>(left: E): Either$1<E, never>;
    match<B>(patterns: {
        Some: (value: never) => B;
        None: () => B;
    }): B;
    toString(): string;
}
declare const None: NoneImpl;
declare function Some<A>(value: A): Option<A>;
/**
 * Option<A> represents an optional value that may or may not be present.
 * It's a type-safe alternative to using null or undefined.
 *
 * @example
 * ```ts
 * import { Option, Some, None } from 'scats';
 *
 * // Creating options
 * const a = Some(42);
 * const b = None;
 * const c = Option.fromNullable(maybeNull);
 *
 * // Using options
 * const result = a
 *   .map(n => n * 2)
 *   .flatMap(n => n > 50 ? Some(n) : None)
 *   .getOrElse(0);
 * ```
 */
/**
 * Option<A> interface that all option implementations must satisfy
 */
interface Option<A> {
    /**
     * Returns true if the option is a Some, false otherwise
     */
    readonly isSome: boolean;
    /**
     * Returns true if the option is a None, false otherwise
     */
    readonly isNone: boolean;
    /**
     * Returns the value if this is a Some, otherwise throws an error
     * @throws Error if the option is None
     */
    get(): A;
    /**
     * Returns the value if this is a Some, otherwise returns the provided default value
     */
    getOrElse<B>(defaultValue: B): A | B;
    /**
     * Returns the value if this is a Some, otherwise returns the result of the provided function
     */
    getOrCall<B>(f: () => B): A | B;
    /**
     * Returns the value if this is a Some, otherwise throws the provided error
     */
    getOrThrow(error: Error): A;
    /**
     * Maps the value if this is a Some, otherwise returns None
     */
    map<B>(f: (a: A) => B): Option<B>;
    /**
     * Maps the value if this is a Some, otherwise returns the provided default value wrapped in Some
     */
    mapOr<B>(defaultValue: B, f: (a: A) => B): Option<B>;
    /**
     * Returns the result of applying f if this is a Some, otherwise returns None
     */
    flatMap<B>(f: (a: A) => Option<B>): Option<B>;
    /**
     * Returns the option if it is a Some, otherwise returns the provided option
     */
    orElse<B>(alternative: Option<B>): Option<A | B>;
    /**
     * Returns the option if it is a Some, otherwise returns the result of the provided function
     */
    orCall<B>(f: () => Option<B>): Option<A | B>;
    /**
     * Returns None if the predicate is not satisfied, otherwise returns this option
     */
    filter(predicate: (a: A) => boolean): Option<A>;
    /**
     * Executes the provided function if this is a Some
     */
    forEach(f: (a: A) => void): void;
    /**
     * Converts the option to an array with the value if it's a Some, or an empty array if it's a None
     */
    toArray(): A[];
    /**
     * Converts this option to an Either with the provided left value if this is a None
     */
    toEither<E>(left: E): Either$1<E, A>;
    /**
     * Returns the result of applying the appropriate function
     */
    match<B>(patterns: {
        Some: (value: A) => B;
        None: () => B;
    }): B;
}
declare namespace Option {
    /**
     * Creates an Option from a nullable value
     */
    function fromNullable<A>(value: A | null | undefined): Option<A>;
    /**
     * Creates an Option from a function that might throw
     */
    function tryCatch<A>(f: () => A): Option<A>;
    /**
     * Returns the first Some in the list, or None if all are None
     */
    function firstSome<A>(...options: Option<A>[]): Option<A>;
    /**
     * Returns a Some containing an array of all values if all options are Some, None otherwise
     */
    function sequence<A>(options: Option<A>[]): Option<A[]>;
    /**
     * Maps an array of values using a function that returns an Option, then sequences the result
     */
    function traverse<A, B>(values: A[], f: (a: A) => Option<B>): Option<B[]>;
}
interface Either$1<E, A> {
    isLeft: boolean;
    isRight: boolean;
    get(): A;
    getLeft(): E;
}

/**
 * Either<E, A> represents a value of one of two possible types: Left (E) or Right (A).
 * Left is conventionally used for errors, while Right is used for success.
 *
 * @example
 * ```ts
 * import { Either, Left, Right } from 'scats';
 *
 * // Creating eithers
 * const success = Right(42);
 * const failure = Left(new Error("Something went wrong"));
 *
 * // Using eithers
 * const result = success
 *   .map(n => n * 2)
 *   .flatMap(n => n > 50 ? Right(n) : Left("Value too small"))
 *   .getOrElse(0);
 * ```
 */

/**
 * Creates a Left instance
 */
declare function Left<E, A = never>(left: E): Either<E, A>;
/**
 * Creates a Right instance
 */
declare function Right<A, E = never>(right: A): Either<E, A>;
/**
 * Either<E, A> interface that all Either implementations must satisfy
 */
interface Either<E, A> {
    /**
     * Returns true if this is a Left, false otherwise
     */
    readonly isLeft: boolean;
    /**
     * Returns true if this is a Right, false otherwise
     */
    readonly isRight: boolean;
    /**
     * Returns the value from this Right, or throws an error if this is a Left
     * @throws Error if this is a Left
     */
    get(): A;
    /**
     * Returns the left value if this is a Left, or throws an error if this is a Right
     * @throws Error if this is a Right
     */
    getLeft(): E;
    /**
     * Returns the value from this Right, or returns the provided default value if this is a Left
     */
    getOrElse<B>(defaultValue: B): A | B;
    /**
     * Returns the value from this Right, or returns the result of the provided function if this is a Left
     */
    getOrCall<B>(f: (e: E) => B): A | B;
    /**
     * Returns the value from this Right, or throws the provided error if this is a Left
     */
    getOrThrow(error: Error): A;
    /**
     * Maps the Right value if this is a Right, otherwise returns this Left unchanged
     */
    map<B>(f: (a: A) => B): Either<E, B>;
    /**
     * Maps the Left value if this is a Left, otherwise returns this Right unchanged
     */
    mapLeft<F>(f: (e: E) => F): Either<F, A>;
    /**
     * Returns the result of applying f if this is a Right, otherwise returns this Left unchanged
     */
    flatMap<B>(f: (a: A) => Either<E, B>): Either<E, B>;
    /**
     * Returns this Right if this is a Right, otherwise returns the provided alternative
     */
    orElse<F, B>(alternative: Either<F, B>): Either<E | F, A | B>;
    /**
     * Returns this Right if this is a Right, otherwise returns the result of the provided function
     */
    orCall<F, B>(f: (e: E) => Either<F, B>): Either<E | F, A | B>;
    /**
     * Executes one of the provided functions based on whether this is a Left or a Right
     */
    fold<B>(onLeft: (e: E) => B, onRight: (a: A) => B): B;
    /**
     * Executes the provided function if this is a Right
     */
    forEach(f: (a: A) => void): void;
    /**
     * Executes the provided function if this is a Left
     */
    forEachLeft(f: (e: E) => void): void;
    /**
     * Converts this Either to an Option, discarding the Left value if this is a Left
     */
    toOption(): Option<A>;
    /**
     * Swaps the Left and Right values of this Either
     */
    swap(): Either<A, E>;
    /**
     * Returns the result of applying the appropriate function
     */
    match<B>(patterns: {
        Left: (value: E) => B;
        Right: (value: A) => B;
    }): B;
}
/**
 * Either namespace containing utility functions
 */
declare namespace Either {
    /**
     * Creates an Either from a function that might throw, capturing the error in the Left
     */
    function tryCatch<A>(f: () => A): Either<unknown, A>;
    /**
     * Returns a Right containing an array of all values if all inputs are Right, otherwise returns the first Left
     */
    function sequence<E, A>(eithers: Either<E, A>[]): Either<E, A[]>;
    /**
     * Maps an array of values using a function that returns an Either, then sequences the result
     */
    function traverse<E, A, B>(values: A[], f: (a: A) => Either<E, B>): Either<E, B[]>;
}

/**
 * Try<A> represents a computation that may either result in a value of type A
 * or an exception. It's similar to Either<Error, A> but specifically for handling exceptions.
 *
 * @example
 * ```ts
 * import { Try, Success, Failure, TryAsync } from 'scats';
 *
 * // Creating instances
 * const a = Try.of(() => JSON.parse('{"valid": "json"}'));
 * const b = Try.of(() => JSON.parse('invalid json'));
 *
 * // Using Try
 * const result = a
 *   .map(obj => obj.valid)
 *   .flatMap(str => Try.of(() => str.toUpperCase()))
 *   .getOrElse("default");
 *
 * // Async version
 * const asyncResult = await TryAsync.of(async () => {
 *   const response = await fetch('https://api.example.com');
 *   return response.json();
 * }).map(data => data.value).toPromise();
 * ```
 */

/**
 * Creates a Success instance
 */
declare function Success<A>(value: A): Try<A>;
/**
 * Creates a Failure instance
 */
declare function Failure<A>(error: Error): Try<A>;
/**
 * Try<A> interface that all Try implementations must satisfy
 */
interface Try<A> {
    /**
     * Returns true if this is a Success, false otherwise
     */
    readonly isSuccess: boolean;
    /**
     * Returns true if this is a Failure, false otherwise
     */
    readonly isFailure: boolean;
    /**
     * Returns the value if this is a Success, or throws the error if this is a Failure
     * @throws Error if this is a Failure
     */
    get(): A;
    /**
     * Returns the value if this is a Success, or returns the provided default value if this is a Failure
     */
    getOrElse<B>(defaultValue: B): A | B;
    /**
     * Returns the error if this is a Failure, or throws if this is a Success
     * @throws Error if this is a Success
     */
    getError(): Error;
    /**
     * Returns a Try containing the exception if this is a Failure, or a Failure if this is a Success
     */
    failed(): Try<Error>;
    /**
     * Maps the value if this is a Success, otherwise returns this Failure unchanged
     */
    map<B>(f: (a: A) => B): Try<B>;
    /**
     * Returns the result of applying f if this is a Success, otherwise returns this Failure unchanged
     */
    flatMap<B>(f: (a: A) => Try<B>): Try<B>;
    /**
     * Recovers from a failure by returning the result of the provided function
     */
    recover<B>(f: (error: Error) => B): Try<A | B>;
    /**
     * Recovers from a failure by returning the result of the provided function
     */
    recoverWith<B>(f: (error: Error) => Try<B>): Try<A | B>;
    /**
     * Transforms this Try to another Try using the provided functions
     */
    transform<B>(s: (a: A) => Try<B>, f: (error: Error) => Try<B>): Try<B>;
    /**
     * Converts this Try to an Option, discarding the error if this is a Failure
     */
    toOption(): Option<A>;
    /**
     * Converts this Try to an Either with the error as Left and value as Right
     */
    toEither(): Either<Error, A>;
    /**
     * Executes one of the provided functions based on whether this is a Success or a Failure
     */
    fold<B>(onFailure: (error: Error) => B, onSuccess: (value: A) => B): B;
    /**
     * Returns the result of applying the appropriate function
     */
    match<B>(patterns: {
        Success: (value: A) => B;
        Failure: (error: Error) => B;
    }): B;
}
/**
 * Try namespace containing utility functions
 */
declare namespace Try {
    /**
     * Creates a Try from a function that might throw
     */
    function of<A>(f: () => A): Try<A>;
    /**
     * Returns a Success containing an array of all values if all tries are Success, otherwise returns the first Failure
     */
    function sequence<A>(tries: Try<A>[]): Try<A[]>;
    /**
     * Maps an array of values using a function that returns a Try, then sequences the result
     */
    function traverse<A, B>(values: A[], f: (a: A) => Try<B>): Try<B[]>;
}
/**
 * TryAsync<A> represents an asynchronous computation that may either result in a value of type A
 * or an exception. It's the asynchronous counterpart to Try<A>.
 */
interface TryAsync<A> {
    /**
     * Maps the value if this is a Success, otherwise returns this Failure unchanged
     */
    map<B>(f: (a: A) => B | Promise<B>): TryAsync<B>;
    /**
     * Returns the result of applying f if this is a Success, otherwise returns this Failure unchanged
     */
    flatMap<B>(f: (a: A) => TryAsync<B> | Promise<TryAsync<B>>): TryAsync<B>;
    /**
     * Recovers from a failure by returning the result of the provided function
     */
    recover<B>(f: (error: Error) => B | Promise<B>): TryAsync<A | B>;
    /**
     * Recovers from a failure by returning the result of the provided function
     */
    recoverWith<B>(f: (error: Error) => TryAsync<B> | Promise<TryAsync<B>>): TryAsync<A | B>;
    /**
     * Converts this async Try to a Promise
     */
    toPromise(): Promise<A>;
}
/**
 * TryAsync namespace containing utility functions
 */
declare namespace TryAsync {
    /**
     * Creates a TryAsync from a function that returns a Promise
     */
    function of<A>(f: () => Promise<A>): TryAsync<A>;
    /**
     * Creates a successful TryAsync
     */
    function success<A>(value: A): TryAsync<A>;
    /**
     * Creates a failed TryAsync
     */
    function failure<A>(error: Error): TryAsync<A>;
    /**
     * Converts a Promise to a TryAsync
     */
    function fromPromise<A>(promise: Promise<A>): TryAsync<A>;
}

/**
 * A default global execution context backed by the JavaScript event loop.
 */
declare class GlobalExecutionContext implements ExecutionContext {
    /**
     * Executes a task asynchronously.
     */
    execute(task: () => void): void;
    /**
     * Reports a failure to the console.
     */
    reportFailure(cause: Error): void;
}
/**
 * An execution context that executes tasks synchronously in the current thread.
 * This is mainly for testing and should be avoided in production.
 */
declare class SynchronousExecutionContext implements ExecutionContext {
    /**
     * Executes a task immediately in the current thread.
     */
    execute(task: () => void): void;
    /**
     * Reports a failure to the console.
     */
    reportFailure(cause: Error): void;
}
/**
 * The execution context is the environment where a computation runs.
 */
interface ExecutionContext {
    /**
     * Executes a task in this execution context.
     */
    execute(task: () => void): void;
    /**
     * Reports an exception that occurred during execution.
     */
    reportFailure(cause: Error): void;
}
/**
 * Execution context utility methods.
 */
declare const ExecutionContext: {
    /**
     * The global execution context.
     */
    global: GlobalExecutionContext;
    /**
     * A synchronous execution context for testing.
     */
    synchronous: SynchronousExecutionContext;
    /**
     * Creates an execution context from a function that executes tasks.
     */
    fromExecutor(executor: (task: () => void) => void, reporter?: (cause: Error) => void): ExecutionContext;
};

/**
 * List<A> represents an immutable linked list structure.
 * It's a singly-linked list that supports efficient prepend operations.
 *
 * @example
 * ```ts
 * import { List } from 'scats';
 *
 * // Creating lists
 * const a = List.of(1, 2, 3);
 * const b = List.empty<number>();
 * const c = a.prepend(0);
 *
 * // Using lists
 * const doubled = a.map(n => n * 2);
 * const summed = a.foldLeft(0, (acc, n) => acc + n);
 * const filtered = a.filter(n => n % 2 === 0);
 * ```
 */

/**
 * List<A> interface that all List implementations must satisfy
 */
interface List<A> extends Iterable<A> {
    /**
     * Returns true if this list is empty, false otherwise
     */
    readonly isEmpty: boolean;
    /**
     * Returns the number of elements in this list
     */
    readonly size: number;
    /**
     * Returns the first element of this list, or throws an error if the list is empty
     * @throws Error if the list is empty
     */
    head(): A;
    /**
     * Returns the rest of this list (all elements except the head), or throws an error if the list is empty
     * @throws Error if the list is empty
     */
    tail(): List<A>;
    /**
     * Returns the first element of this list as an Option, or None if the list is empty
     */
    headOption(): Option<A>;
    /**
     * Returns the rest of this list as an Option, or None if the list is empty
     */
    tailOption(): Option<List<A>>;
    /**
     * Returns a new list with the provided element prepended to this list
     */
    prepend(element: A): List<A>;
    /**
     * Returns a new list with the provided elements appended to this list
     */
    append(element: A): List<A>;
    /**
     * Returns a new list that is the result of concatenating this list with the provided list
     */
    concat(that: List<A>): List<A>;
    /**
     * Returns a new list that is the result of applying the provided function to each element
     */
    map<B>(f: (a: A) => B): List<B>;
    /**
     * Returns a new list that is the result of applying the provided function to each element
     * and flattening the results
     */
    flatMap<B>(f: (a: A) => List<B>): List<B>;
    /**
     * Returns a new list containing only the elements that satisfy the provided predicate
     */
    filter(predicate: (a: A) => boolean): List<A>;
    /**
     * Returns a tuple of two lists, where the first list contains all elements that satisfy
     * the provided predicate, and the second list contains all elements that don't satisfy the predicate
     */
    partition(predicate: (a: A) => boolean): [List<A>, List<A>];
    /**
     * Returns true if any element in this list satisfies the provided predicate, false otherwise
     */
    exists(predicate: (a: A) => boolean): boolean;
    /**
     * Returns true if all elements in this list satisfy the provided predicate, false otherwise
     */
    forAll(predicate: (a: A) => boolean): boolean;
    /**
     * Returns the result of applying the provided function to each element, starting with the provided initial value
     */
    foldLeft<B>(initial: B, f: (acc: B, a: A) => B): B;
    /**
     * Returns the result of applying the provided function to each element, starting with the provided initial value,
     * working from right to left
     */
    foldRight<B>(initial: B, f: (a: A, acc: B) => B): B;
    /**
     * Executes the provided function for each element in this list
     */
    forEach(f: (a: A) => void): void;
    /**
     * Returns a new list containing the elements at the specified indices
     */
    slice(start: number, end?: number): List<A>;
    /**
     * Returns a new list with the first n elements
     */
    take(n: number): List<A>;
    /**
     * Returns a new list with all elements except the first n
     */
    drop(n: number): List<A>;
    /**
     * Returns a new list with elements while the predicate is satisfied
     */
    takeWhile(predicate: (a: A) => boolean): List<A>;
    /**
     * Returns a new list without elements while the predicate is satisfied
     */
    dropWhile(predicate: (a: A) => boolean): List<A>;
    /**
     * Returns the element at the specified index, or throws an error if the index is out of bounds
     * @throws Error if the index is out of bounds
     */
    get(index: number): A;
    /**
     * Returns the element at the specified index as an Option, or None if the index is out of bounds
     */
    getOption(index: number): Option<A>;
    /**
     * Returns a new list with the element at the specified index replaced with the provided element,
     * or the same list if the index is out of bounds
     */
    updateAt(index: number, element: A): List<A>;
    /**
     * Returns the index of the first occurrence of the specified element, or -1 if the element is not found
     */
    indexOf(element: A): number;
    /**
     * Returns true if this list contains the specified element, false otherwise
     */
    contains(element: A): boolean;
    /**
     * Returns a new list with distinct elements (removes duplicates)
     */
    distinct(): List<A>;
    /**
     * Returns a new list with the elements in reverse order
     */
    reverse(): List<A>;
    /**
     * Returns a new list sorted according to the natural ordering of the elements
     */
    sorted(compareFn?: (a: A, b: A) => number): List<A>;
    /**
     * Converts this list to an array
     */
    toArray(): A[];
    /**
     * Returns a string representation of this list
     */
    toString(): string;
}
/**
 * List namespace containing utility functions
 */
declare namespace List {
    /**
     * Creates a list containing the provided elements
     */
    function of<A>(...elements: A[]): List<A>;
    /**
     * Creates a list from an array
     */
    function fromArray<A>(array: A[]): List<A>;
    /**
     * Creates a list from an iterable
     */
    function fromIterable<A>(iterable: Iterable<A>): List<A>;
    /**
     * Creates an empty list
     */
    function empty<A>(): List<A>;
    /**
     * Creates a list with elements produced by the specified function
     */
    function fill<A>(n: number, f: (index: number) => A): List<A>;
    /**
     * Creates a list with the specified element repeated n times
     */
    function repeat<A>(element: A, n: number): List<A>;
    /**
     * Creates a list with numbers from start (inclusive) to end (exclusive)
     */
    function range(start: number, end: number, step?: number): List<number>;
    /**
     * Zips two lists together, element by element
     */
    function zip<A, B>(as: List<A>, bs: List<B>): List<[A, B]>;
    /**
     * Maps two lists with the provided function
     */
    function map2<A, B, C>(as: List<A>, bs: List<B>, f: (a: A, b: B) => C): List<C>;
}

/**
 * Map<K, V> represents an immutable key-value map.
 * It's implemented as a balanced binary search tree for efficient operations.
 *
 * @example
 * ```ts
 * import { Map } from 'scats';
 *
 * // Creating maps
 * const a = Map.of([["a", 1], ["b", 2], ["c", 3]]);
 * const b = Map.empty<string, number>();
 * const c = a.set("d", 4);
 *
 * // Using maps
 * const value = a.get("a"); // Some(1)
 * const notFound = a.get("z"); // None
 * const updated = a.update("a", n => n * 2); // Map(["a", 2], ["b", 2], ["c", 3])
 * ```
 */

/**
 * Map<K, V> interface that all Map implementations must satisfy
 */
interface Map<K, V> {
    /**
     * Returns true if this map is empty, false otherwise
     */
    readonly isEmpty: boolean;
    /**
     * Returns the number of key-value pairs in this map
     */
    readonly size: number;
    /**
     * Returns the keys in this map
     */
    readonly keys: List<K>;
    /**
     * Returns the values in this map
     */
    readonly values: List<V>;
    /**
     * Returns the key-value pairs in this map
     */
    readonly entries: List<[K, V]>;
    /**
     * Returns the value associated with the specified key as an Option, or None if the key is not found
     */
    get(key: K): Option<V>;
    /**
     * Returns the value associated with the specified key, or the provided default value if the key is not found
     */
    getOrElse<U>(key: K, defaultValue: U): V | U;
    /**
     * Returns a new map with the specified key-value pair added or updated
     */
    set(key: K, value: V): Map<K, V>;
    /**
     * Returns a new map with the specified key-value pairs added or updated
     */
    setAll(entries: Iterable<[K, V]>): Map<K, V>;
    /**
     * Returns a new map with the specified key-value pair removed
     */
    remove(key: K): Map<K, V>;
    /**
     * Returns a new map with the specified keys removed
     */
    removeAll(keys: Iterable<K>): Map<K, V>;
    /**
     * Returns a new map with the value associated with the specified key updated by applying the provided function,
     * or the same map if the key is not found
     */
    update(key: K, f: (value: V) => V): Map<K, V>;
    /**
     * Returns a new map with the value associated with the specified key updated by applying the provided function,
     * or a new map with the specified key-value pair added if the key is not found
     */
    updateOrSet(key: K, f: (value: Option<V>) => V): Map<K, V>;
    /**
     * Returns a new map that is the result of merging this map with the specified map
     */
    merge(that: Map<K, V>): Map<K, V>;
    /**
     * Returns a new map that is the result of applying the provided function to each key-value pair
     */
    map<W>(f: (value: V, key: K) => W): Map<K, W>;
    /**
     * Returns a new map containing only the key-value pairs that satisfy the provided predicate
     */
    filter(predicate: (value: V, key: K) => boolean): Map<K, V>;
    /**
     * Returns true if any key-value pair in this map satisfies the provided predicate, false otherwise
     */
    exists(predicate: (value: V, key: K) => boolean): boolean;
    /**
     * Returns true if all key-value pairs in this map satisfy the provided predicate, false otherwise
     */
    forAll(predicate: (value: V, key: K) => boolean): boolean;
    /**
     * Returns the result of applying the provided function to each key-value pair, starting with the provided initial value
     */
    foldLeft<U>(initial: U, f: (acc: U, value: V, key: K) => U): U;
    /**
     * Executes the provided function for each key-value pair in this map
     */
    forEach(f: (value: V, key: K) => void): void;
    /**
     * Returns true if this map contains the specified key, false otherwise
     */
    has(key: K): boolean;
    /**
     * Returns a native JavaScript Map containing the same key-value pairs as this map
     */
    toNativeMap(): globalThis.Map<K, V>;
    /**
     * Returns a string representation of this map
     */
    toString(): string;
}
/**
 * Map namespace containing utility functions
 */
declare namespace Map {
    /**
     * Creates a map from the provided entries
     */
    function of<K, V>(entries: Iterable<[K, V]>): Map<K, V>;
    /**
     * Creates a map from a list of key-value pairs
     */
    function fromList<K, V>(entries: List<[K, V]>): Map<K, V>;
    /**
     * Creates a map from a native JavaScript Map
     */
    function fromNativeMap<K, V>(map: globalThis.Map<K, V>): Map<K, V>;
    /**
     * Creates an empty map
     */
    function empty<K, V>(): Map<K, V>;
    /**
     * Creates a map from a list of keys and a function that computes values
     */
    function fromKeys<K, V>(keys: List<K>, f: (key: K) => V): Map<K, V>;
    /**
     * Creates a map from a list of values and a function that computes keys
     */
    function fromValues<K, V>(values: List<V>, f: (value: V) => K): Map<K, V>;
}

/**
 * Set<A> represents an immutable set of unique values.
 * It's a collection of unique elements with efficient add, remove, and contains operations.
 *
 * @example
 * ```ts
 * import { Set } from 'scats';
 *
 * // Creating sets
 * const a = Set.of(1, 2, 3);
 * const b = Set.empty<number>();
 * const c = a.add(4);
 *
 * // Using sets
 * const union = a.union(Set.of(3, 4, 5)); // Set(1, 2, 3, 4, 5)
 * const intersection = a.intersection(Set.of(2, 3, 4)); // Set(2, 3)
 * const difference = a.difference(Set.of(2, 3)); // Set(1)
 * ```
 */

/**
 * Set<A> interface that all Set implementations must satisfy
 */
interface Set<A> {
    /**
     * Returns true if this set is empty, false otherwise
     */
    readonly isEmpty: boolean;
    /**
     * Returns the number of elements in this set
     */
    readonly size: number;
    /**
     * Returns the elements in this set
     */
    readonly values: List<A>;
    /**
     * Returns true if this set contains the specified element, false otherwise
     */
    contains(element: A): boolean;
    /**
     * Returns a new set with the specified element added
     */
    add(element: A): Set<A>;
    /**
     * Returns a new set with the specified elements added
     */
    addAll(elements: Iterable<A>): Set<A>;
    /**
     * Returns a new set with the specified element removed
     */
    remove(element: A): Set<A>;
    /**
     * Returns a new set with the specified elements removed
     */
    removeAll(elements: Iterable<A>): Set<A>;
    /**
     * Returns a new set that is the union of this set and the specified set
     */
    union(that: Set<A>): Set<A>;
    /**
     * Returns a new set that is the intersection of this set and the specified set
     */
    intersection(that: Set<A>): Set<A>;
    /**
     * Returns a new set that is the difference of this set and the specified set
     */
    difference(that: Set<A>): Set<A>;
    /**
     * Returns true if this set is a subset of the specified set, false otherwise
     */
    isSubsetOf(that: Set<A>): boolean;
    /**
     * Returns true if this set is a proper subset of the specified set, false otherwise
     */
    isProperSubsetOf(that: Set<A>): boolean;
    /**
     * Returns true if this set is a superset of the specified set, false otherwise
     */
    isSupersetOf(that: Set<A>): boolean;
    /**
     * Returns true if this set is a proper superset of the specified set, false otherwise
     */
    isProperSupersetOf(that: Set<A>): boolean;
    /**
     * Returns a new set that is the result of applying the provided function to each element
     */
    map<B>(f: (a: A) => B): Set<B>;
    /**
     * Returns a new set containing only the elements that satisfy the provided predicate
     */
    filter(predicate: (a: A) => boolean): Set<A>;
    /**
     * Returns true if any element in this set satisfies the provided predicate, false otherwise
     */
    exists(predicate: (a: A) => boolean): boolean;
    /**
     * Returns true if all elements in this set satisfy the provided predicate, false otherwise
     */
    forAll(predicate: (a: A) => boolean): boolean;
    /**
     * Returns the result of applying the provided function to each element, starting with the provided initial value
     */
    foldLeft<B>(initial: B, f: (acc: B, a: A) => B): B;
    /**
     * Executes the provided function for each element in this set
     */
    forEach(f: (a: A) => void): void;
    /**
     * Partitions this set into two sets according to the provided predicate
     */
    partition(predicate: (a: A) => boolean): [Set<A>, Set<A>];
    /**
     * Converts this set to a native JavaScript Set
     */
    toNativeSet(): globalThis.Set<A>;
    /**
     * Converts this set to an array
     */
    toArray(): A[];
    /**
     * Returns a string representation of this set
     */
    toString(): string;
}
/**
 * Set namespace containing utility functions
 */
declare namespace Set {
    /**
     * Creates a set containing the provided elements
     */
    function of<A>(...elements: A[]): Set<A>;
    /**
     * Creates a set from the provided iterable
     */
    function fromIterable<A>(iterable: Iterable<A>): Set<A>;
    /**
     * Creates a set from a native JavaScript Set
     */
    function fromNativeSet<A>(set: globalThis.Set<A>): Set<A>;
    /**
     * Creates an empty set
     */
    function empty<A>(): Set<A>;
}

/**
 * Represents a collection of elements that can be iterated over.
 * This trait is the base for all collection types in the library.
 */
interface Iterable$1<A> {
    /**
     * Returns an iterator that yields every element in the collection.
     */
    iterator(): Iterator<A>;
    /**
     * Implements the iterable protocol for for...of loops
     */
    [Symbol.iterator](): Iterator<A>;
    /**
     * Executes a function for each element in the collection.
     */
    forEach(f: (a: A) => void): void;
    /**
     * Returns a new collection containing the results of applying the given function
     * to each element of this collection.
     */
    map<B>(f: (a: A) => B): Iterable$1<B>;
    /**
     * Returns a new collection containing the results of applying the given collection-valued function
     * to each element of this collection and concatenating the results.
     */
    flatMap<B>(f: (a: A) => Iterable$1<B>): Iterable$1<B>;
    /**
     * Returns a new collection containing the results of applying the given partial function
     * to each element of this collection for which it is defined and collecting the results.
     */
    collect<B>(f: (a: A) => Option<B>): Iterable$1<B>;
    /**
     * Returns a new collection consisting of the elements of both this collection and the other collection.
     */
    concat(other: Iterable$1<A>): Iterable$1<A>;
    /**
     * Returns a new collection consisting of those elements of this collection that satisfy the predicate.
     */
    filter(p: (a: A) => boolean): Iterable$1<A>;
    /**
     * Returns a new collection consisting of those elements of this collection that do not satisfy the predicate.
     */
    filterNot(p: (a: A) => boolean): Iterable$1<A>;
    /**
     * Returns a non-strict filter of this collection.
     * Subsequent calls to map, flatMap, foreach, and withFilter will only apply to those elements
     * of this collection for which the condition p is true.
     */
    withFilter(p: (a: A) => boolean): Iterable$1<A>;
    /**
     * Returns the first element of this collection.
     * @throws Error if the collection is empty
     */
    head(): A;
    /**
     * Returns the first element of this collection in an option value, or None if the collection is empty.
     */
    headOption(): Option<A>;
    /**
     * Returns the last element of this collection.
     * @throws Error if the collection is empty
     */
    last(): A;
    /**
     * Returns the last element of this collection in an option value, or None if the collection is empty.
     */
    lastOption(): Option<A>;
    /**
     * Returns an option containing the first element in this collection that satisfies the predicate,
     * or None if no element qualifies.
     */
    find(p: (a: A) => boolean): Option<A>;
    /**
     * Returns the rest of the collection except the first element.
     * @throws Error if the collection is empty
     */
    tail(): Iterable$1<A>;
    /**
     * Returns the rest of the collection except the last element.
     * @throws Error if the collection is empty
     */
    init(): Iterable$1<A>;
    /**
     * Returns a collection consisting of elements in some index range of this collection.
     */
    slice(from: number, to: number): Iterable$1<A>;
    /**
     * Returns a collection consisting of the first n elements of this collection.
     */
    take(n: number): Iterable$1<A>;
    /**
     * Returns the rest of the collection except the first n elements.
     */
    drop(n: number): Iterable$1<A>;
    /**
     * Returns the longest prefix of elements in the collection that all satisfy the predicate.
     */
    takeWhile(p: (a: A) => boolean): Iterable$1<A>;
    /**
     * Returns the collection without the longest prefix of elements that all satisfy the predicate.
     */
    dropWhile(p: (a: A) => boolean): Iterable$1<A>;
    /**
     * Returns a collection consisting of the last n elements of this collection.
     */
    takeRight(n: number): Iterable$1<A>;
    /**
     * Returns the rest of the collection except the last n elements.
     */
    dropRight(n: number): Iterable$1<A>;
    /**
     * Split this collection at a position, giving the pair of collections (take n, drop n).
     */
    splitAt(n: number): [Iterable$1<A>, Iterable$1<A>];
    /**
     * Split this collection according to a predicate, giving the pair of collections
     * (takeWhile p, dropWhile p).
     */
    span(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
    /**
     * Split this collection into a pair of collections; one with elements that satisfy the predicate,
     * the other with elements that do not.
     */
    partition(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
    /**
     * Partition this collection into a map of collections according to a discriminator function.
     */
    groupBy<K>(f: (a: A) => K): globalThis.Map<K, Iterable$1<A>>;
    /**
     * Tests whether the predicate holds for all elements of this collection.
     */
    forall(p: (a: A) => boolean): boolean;
    /**
     * Tests whether the predicate holds for some element of this collection.
     */
    exists(p: (a: A) => boolean): boolean;
    /**
     * Returns the number of elements in this collection that satisfy the predicate.
     */
    count(p: (a: A) => boolean): number;
    /**
     * Apply binary operation op between successive elements of this collection,
     * going left to right and starting with z.
     */
    foldLeft<B>(z: B, op: (b: B, a: A) => B): B;
    /**
     * Apply binary operation op between successive elements of this collection,
     * going right to left and starting with z.
     */
    foldRight<B>(z: B, op: (a: A, b: B) => B): B;
    /**
     * Apply binary operation op between successive elements of non-empty collection,
     * going left to right.
     * @throws Error if the collection is empty
     */
    reduceLeft(op: (a: A, b: A) => A): A;
    /**
     * Apply binary operation op between successive elements of non-empty collection,
     * going right to left.
     * @throws Error if the collection is empty
     */
    reduceRight(op: (a: A, b: A) => A): A;
    /**
     * Returns the sum of the numeric element values of this collection.
     * @throws Error if the collection is empty or contains non-numeric values
     */
    sum(): number;
    /**
     * Returns the product of the numeric element values of this collection.
     * @throws Error if the collection is empty or contains non-numeric values
     */
    product(): number;
    /**
     * Returns the minimum of the ordered element values of this collection.
     * @throws Error if the collection is empty
     */
    min(): A;
    /**
     * Returns the maximum of the ordered element values of this collection.
     * @throws Error if the collection is empty
     */
    max(): A;
    /**
     * Like min but returns None if the collection is empty.
     */
    minOption(): Option<A>;
    /**
     * Like max but returns None if the collection is empty.
     */
    maxOption(): Option<A>;
    /**
     * Converts the collection to a string that shows all elements between separators
     * enclosed in strings start and end.
     */
    mkString(start?: string, sep?: string, end?: string): string;
    /**
     * Returns a collection of pairs of corresponding elements from this collection and the other collection.
     */
    zip<B>(other: Iterable$1<B>): Iterable$1<[A, B]>;
    /**
     * Returns a collection of pairs of corresponding elements from this collection and the other collection,
     * where the shorter sequence is extended to match the longer one by appending elements x or y.
     */
    zipAll<B>(other: Iterable$1<B>, thisElem: A, thatElem: B): Iterable$1<[A, B]>;
    /**
     * Returns a collection of pairs of elements from this collection with their indices.
     */
    zipWithIndex(): Iterable$1<[A, number]>;
    /**
     * Tests whether the collection is empty.
     */
    isEmpty(): boolean;
    /**
     * Tests whether the collection contains elements.
     */
    nonEmpty(): boolean;
    /**
     * Returns the number of elements in the collection.
     */
    size(): number;
    /**
     * Returns the number of elements, if this one takes constant time to compute, otherwise -1.
     */
    knownSize(): number;
    /**
     * Returns a negative value if this collection is shorter than the other collection,
     * a positive value if it is longer, and 0 if they have the same size.
     *
     * Can also be called with a number to compare the collection size with that number.
     */
    sizeCompare(other: Iterable$1<any> | number): number;
    /**
     * Returns an iterator that yields fixed-sized "chunks" of this collection.
     */
    grouped(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
    /**
     * Returns an iterator that yields a sliding fixed-sized window of elements in this collection.
     */
    sliding(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
    /**
     * Converts the collection to an array.
     */
    toArray(): A[];
    /**
     * Converts the collection to a list.
     */
    toList(): List<A>;
    /**
     * Converts the collection to a set.
     */
    toSet(): Set<A>;
    /**
     * Converts the collection to a map.
     * @throws Error if the collection does not have pairs as elements
     */
    toMap<K, V>(): Map<K, V>;
}
/**
 * Abstract base class implementing the Iterable trait.
 * This provides default implementations for many methods based on the iterator method.
 */
declare abstract class AbstractIterable<A> implements Iterable$1<A> {
    abstract iterator(): Iterator<A>;
    [Symbol.iterator](): Iterator<A>;
    forEach(f: (a: A) => void): void;
    map<B>(f: (a: A) => B): Iterable$1<B>;
    flatMap<B>(f: (a: A) => Iterable$1<B>): Iterable$1<B>;
    collect<B>(f: (a: A) => Option<B>): Iterable$1<B>;
    concat(other: Iterable$1<A>): Iterable$1<A>;
    filter(p: (a: A) => boolean): Iterable$1<A>;
    filterNot(p: (a: A) => boolean): Iterable$1<A>;
    withFilter(p: (a: A) => boolean): Iterable$1<A>;
    head(): A;
    headOption(): Option<A>;
    last(): A;
    lastOption(): Option<A>;
    find(p: (a: A) => boolean): Option<A>;
    tail(): Iterable$1<A>;
    init(): Iterable$1<A>;
    slice(from: number, to: number): Iterable$1<A>;
    take(n: number): Iterable$1<A>;
    drop(n: number): Iterable$1<A>;
    takeWhile(p: (a: A) => boolean): Iterable$1<A>;
    dropWhile(p: (a: A) => boolean): Iterable$1<A>;
    takeRight(n: number): Iterable$1<A>;
    dropRight(n: number): Iterable$1<A>;
    splitAt(n: number): [Iterable$1<A>, Iterable$1<A>];
    span(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
    partition(p: (a: A) => boolean): [Iterable$1<A>, Iterable$1<A>];
    groupBy<K>(f: (a: A) => K): globalThis.Map<K, Iterable$1<A>>;
    forall(p: (a: A) => boolean): boolean;
    exists(p: (a: A) => boolean): boolean;
    count(p: (a: A) => boolean): number;
    foldLeft<B>(z: B, op: (b: B, a: A) => B): B;
    foldRight<B>(z: B, op: (a: A, b: B) => B): B;
    reduceLeft(op: (a: A, b: A) => A): A;
    reduceRight(op: (a: A, b: A) => A): A;
    sum(): number;
    product(): number;
    min(): A;
    max(): A;
    minOption(): Option<A>;
    maxOption(): Option<A>;
    mkString(start?: string, sep?: string, end?: string): string;
    zip<B>(other: Iterable$1<B>): Iterable$1<[A, B]>;
    zipAll<B>(other: Iterable$1<B>, thisElem: A, thatElem: B): Iterable$1<[A, B]>;
    zipWithIndex(): Iterable$1<[A, number]>;
    isEmpty(): boolean;
    nonEmpty(): boolean;
    size(): number;
    knownSize(): number;
    sizeCompare(other: Iterable$1<any> | number): number;
    grouped(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
    sliding(size: number): Iterator<Iterable$1<A>> & Iterable$1<Iterable$1<A>>;
    toArray(): A[];
    toList(): List<A>;
    toSet(): Set<A>;
    toMap<K, V>(): Map<K, V>;
}

/**
 * The Seq trait represents sequences. A sequence is a kind of iterable that has a length
 * and whose elements have fixed index positions, starting from 0.
 */
interface Seq<A> extends Iterable$1<A> {
    /**
     * Returns the element at the specified index.
     */
    apply(i: number): A;
    /**
     * Tests whether an index is contained in this sequence's range.
     */
    isDefinedAt(i: number): boolean;
    /**
     * Returns the index range of this sequence, from 0 to length - 1.
     */
    indices(): Iterable$1<number>;
    /**
     * Compares the length of this sequence with a specified value.
     * Returns -1 if shorter, 0 if equal, 1 if longer.
     */
    lengthCompare(len: number): number;
    /**
     * Finds the index of the first occurrence of an element.
     */
    indexOf(elem: A, from?: number): number;
    /**
     * Finds the index of the last occurrence of an element.
     */
    lastIndexOf(elem: A, end?: number): number;
    /**
     * Finds the first index where a subsequence occurs.
     */
    indexOfSlice<B>(that: Seq<B>, from?: number): number;
    /**
     * Finds the last index where a subsequence occurs.
     */
    lastIndexOfSlice<B>(that: Seq<B>, end?: number): number;
    /**
     * Finds the first index where a predicate is satisfied.
     */
    indexWhere(p: (a: A) => boolean, from?: number): number;
    /**
     * Finds the last index where a predicate is satisfied.
     */
    lastIndexWhere(p: (a: A) => boolean, end?: number): number;
    /**
     * Returns the length of the longest segment of elements starting at a given index that all satisfy a predicate.
     */
    segmentLength(p: (a: A) => boolean, from?: number): number;
    /**
     * Returns a new sequence with an element prepended.
     */
    prepended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements prepended.
     */
    prependedAll<B>(prefix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with an element appended.
     */
    appended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements appended.
     */
    appendedAll<B>(suffix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence padded to a given length with a given value.
     */
    padTo(len: number, elem: A): Seq<A>;
    /**
     * Returns a new sequence with a slice of another sequence patched in.
     */
    patch<B>(from: number, patch: Seq<B>, replaced: number): Seq<A | B>;
    /**
     * Returns a new sequence with one element replaced.
     */
    updated(index: number, elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements sorted.
     */
    sorted(implicit?: (a: A, b: A) => number): Seq<A>;
    /**
     * Returns a new sequence sorted according to a comparison function.
     */
    sortWith(lt: (a: A, b: A) => boolean): Seq<A>;
    /**
     * Returns a new sequence sorted according to a key function.
     */
    sortBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): Seq<A>;
    /**
     * Returns a new sequence with elements in reverse order.
     */
    reverse(): Seq<A>;
    /**
     * Returns an iterator yielding elements in reverse order.
     */
    reverseIterator(): Iterator<A>;
    /**
     * Tests whether this sequence starts with a given sequence.
     */
    startsWith<B>(that: Seq<B>, offset?: number): boolean;
    /**
     * Tests whether this sequence ends with a given sequence.
     */
    endsWith<B>(that: Seq<B>): boolean;
    /**
     * Tests whether this sequence contains a given value as an element.
     */
    contains(elem: A): boolean;
    /**
     * Tests whether this sorted sequence contains a given value.
     */
    search(elem: A): number;
    /**
     * Tests whether this sequence contains a given sequence as a slice.
     */
    containsSlice<B>(that: Seq<B>): boolean;
    /**
     * Tests whether corresponding elements of this sequence and another satisfy a predicate.
     */
    corresponds<B>(that: Seq<B>, p: (a: A, b: B) => boolean): boolean;
    /**
     * Returns the multi-set intersection of this sequence and another.
     */
    intersect<B>(that: Seq<B>): Seq<A>;
    /**
     * Returns the multi-set difference of this sequence and another.
     */
    diff<B>(that: Seq<B>): Seq<A>;
    /**
     * Returns a new sequence with no duplicate elements.
     */
    distinct(): Seq<A>;
    /**
     * Returns a new sequence with no duplicate elements according to a transformation function.
     */
    distinctBy<B>(f: (a: A) => B): Seq<A>;
}
/**
 * The LinearSeq trait represents sequences that have efficient head and tail operations.
 */
interface LinearSeq<A> extends Seq<A> {
}
/**
 * The IndexedSeq trait represents sequences that have efficient apply and length operations.
 */
interface IndexedSeq<A> extends Seq<A> {
}
/**
 * The mutable IndexedSeq trait adds in-place operations.
 */
interface MutableIndexedSeq<A> extends IndexedSeq<A> {
    /**
     * Updates the element at the given index.
     */
    update(index: number, elem: A): void;
    /**
     * Transforms all elements of this sequence in place.
     */
    mapInPlace(f: (a: A) => A): this;
    /**
     * Sorts this sequence in place.
     */
    sortInPlace(implicit?: (a: A, b: A) => number): this;
    /**
     * Sorts this sequence in place according to a comparison function.
     */
    sortInPlaceWith(lt: (a: A, b: A) => boolean): this;
    /**
     * Sorts this sequence in place according to a key function.
     */
    sortInPlaceBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): this;
}
/**
 * The Buffer trait represents sequences that allow addition, insertion, and removal of elements.
 */
interface Buffer<A> extends MutableIndexedSeq<A> {
    /**
     * Appends an element to this buffer.
     */
    append(elem: A): this;
    /**
     * Appends all elements of a collection to this buffer.
     */
    appendAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Prepends an element to this buffer.
     */
    prepend(elem: A): this;
    /**
     * Prepends all elements of a collection to this buffer.
     */
    prependAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Inserts an element at a given index.
     */
    insert(idx: number, elem: A): this;
    /**
     * Inserts elements at a given index.
     */
    insertAll<B extends A>(idx: number, xs: Iterable$1<B>): this;
    /**
     * Pads this buffer to a given length by appending a value.
     */
    padToInPlace(len: number, elem: A): this;
    /**
     * Removes an element from this buffer.
     */
    subtractOne(elem: A): this;
    /**
     * Removes all elements in a collection from this buffer.
     */
    subtractAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Removes the element at a given index.
     */
    remove(idx: number, count?: number): A;
    /**
     * Removes the first n elements.
     */
    trimStart(n: number): this;
    /**
     * Removes the last n elements.
     */
    trimEnd(n: number): this;
    /**
     * Removes all elements from this buffer.
     */
    clear(): this;
    /**
     * Replaces a slice of this buffer with another sequence.
     */
    patchInPlace<B extends A>(from: number, patch: Iterable$1<B>, replaced: number): this;
    /**
     * Returns a new buffer with the same elements as this buffer.
     */
    clone(): Buffer<A>;
}

/**
 * Abstract base class for sequence implementations.
 */
declare abstract class AbstractSeq<A> extends AbstractIterable<A> implements Seq<A> {
    /**
     * Returns the element at the specified index.
     */
    apply(i: number): A;
    /**
     * Tests whether an index is contained in this sequence's range.
     */
    isDefinedAt(i: number): boolean;
    /**
     * Returns the index range of this sequence, from 0 to length - 1.
     */
    indices(): Iterable$1<number>;
    /**
     * Compares the length of this sequence with a specified value.
     */
    lengthCompare(len: number): number;
    /**
     * Finds the index of the first occurrence of an element.
     */
    indexOf(elem: A, from?: number): number;
    /**
     * Finds the index of the last occurrence of an element.
     */
    lastIndexOf(elem: A, end?: number): number;
    /**
     * Finds the first index where a subsequence occurs.
     */
    indexOfSlice<B>(that: Seq<B>, from?: number): number;
    /**
     * Finds the last index where a subsequence occurs.
     */
    lastIndexOfSlice<B>(that: Seq<B>, end?: number): number;
    /**
     * Finds the first index where a predicate is satisfied.
     */
    indexWhere(p: (a: A) => boolean, from?: number): number;
    /**
     * Finds the last index where a predicate is satisfied.
     */
    lastIndexWhere(p: (a: A) => boolean, end?: number): number;
    /**
     * Returns the length of the longest segment of elements starting at a given index that all satisfy a predicate.
     */
    segmentLength(p: (a: A) => boolean, from?: number): number;
    /**
     * Returns a new sequence with an element prepended.
     */
    abstract prepended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements prepended.
     */
    abstract prependedAll<B>(prefix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with an element appended.
     */
    abstract appended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements appended.
     */
    abstract appendedAll<B>(suffix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence padded to a given length with a given value.
     */
    padTo(len: number, elem: A): Seq<A>;
    /**
     * Returns a new sequence with a slice of another sequence patched in.
     */
    abstract patch<B>(from: number, patch: Seq<B>, replaced: number): Seq<A | B>;
    /**
     * Returns a new sequence with one element replaced.
     */
    abstract updated(index: number, elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements sorted.
     */
    sorted(implicit?: (a: A, b: A) => number): Seq<A>;
    /**
     * Returns a new sequence sorted according to a comparison function.
     */
    sortWith(lt: (a: A, b: A) => boolean): Seq<A>;
    /**
     * Returns a new sequence sorted according to a key function.
     */
    sortBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): Seq<A>;
    /**
     * Returns a new sequence with elements in reverse order.
     */
    reverse(): Seq<A>;
    /**
     * Returns an iterator yielding elements in reverse order.
     */
    reverseIterator(): Iterator<A>;
    /**
     * Tests whether this sequence starts with a given sequence.
     */
    startsWith<B>(that: Seq<B>, offset?: number): boolean;
    /**
     * Tests whether this sequence ends with a given sequence.
     */
    endsWith<B>(that: Seq<B>): boolean;
    /**
     * Tests whether this sequence contains a given value as an element.
     */
    contains(elem: A): boolean;
    /**
     * Tests whether this sorted sequence contains a given value.
     */
    search(elem: A): number;
    /**
     * Tests whether this sequence contains a given sequence as a slice.
     */
    containsSlice<B>(that: Seq<B>): boolean;
    /**
     * Tests whether corresponding elements of this sequence and another satisfy a predicate.
     */
    corresponds<B>(that: Seq<B>, p: (a: A, b: B) => boolean): boolean;
    /**
     * Returns the multi-set intersection of this sequence and another.
     */
    intersect<B>(that: Seq<B>): Seq<A>;
    /**
     * Returns the multi-set difference of this sequence and another.
     */
    diff<B>(that: Seq<B>): Seq<A>;
    /**
     * Returns a new sequence with no duplicate elements.
     */
    distinct(): Seq<A>;
    /**
     * Returns a new sequence with no duplicate elements according to a transformation function.
     */
    distinctBy<B>(f: (a: A) => B): Seq<A>;
    /**
     * Helper method to compare elements for equality.
     */
    protected equals(a: any, b: any): boolean;
    /**
     * Helper method to create a sequence from an array.
     */
    protected abstract fromArray(arr: A[]): Seq<A>;
}

/**
 * An implementation of IndexedSeq backed by an array.
 */
declare class ArraySeq<A> extends AbstractSeq<A> implements IndexedSeq<A> {
    private elements;
    /**
     * Creates a new ArraySeq from the given elements.
     */
    constructor(elements: A[]);
    /**
     * Creates a new ArraySeq from the given elements.
     */
    static of<A>(...elements: A[]): ArraySeq<A>;
    /**
     * Creates a new ArraySeq from an iterable.
     */
    static from<A>(iterable: Iterable$1<A>): ArraySeq<A>;
    /**
     * Creates an empty ArraySeq.
     */
    static empty<A>(): ArraySeq<A>;
    /**
     * Returns an iterator over the elements of this sequence.
     */
    iterator(): Iterator<A>;
    /**
     * Returns the element at the specified index.
     * This is more efficient than the default implementation.
     */
    apply(i: number): A;
    /**
     * Returns the size of this sequence.
     * This is more efficient than the default implementation.
     */
    size(): number;
    /**
     * Returns the known size of this sequence.
     * This is more efficient than the default implementation.
     */
    knownSize(): number;
    /**
     * Returns a new sequence with an element prepended.
     */
    prepended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements prepended.
     */
    prependedAll<B>(prefix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with an element appended.
     */
    appended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements appended.
     */
    appendedAll<B>(suffix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with a slice of another sequence patched in.
     */
    patch<B>(from: number, patch: Seq<B>, replaced: number): Seq<A | B>;
    /**
     * Returns a new sequence with one element replaced.
     */
    updated(index: number, elem: A): Seq<A>;
    /**
     * Helper method to create a sequence from an array.
     */
    protected fromArray(arr: A[]): Seq<A>;
}

/**
 * A mutable buffer implementation backed by an array.
 */
declare class ArrayBuffer<A> extends AbstractSeq<A> implements Buffer<A> {
    private elements;
    /**
     * Creates a new ArrayBuffer from the given elements.
     */
    constructor(elements?: A[]);
    /**
     * Creates a new ArrayBuffer from the given elements.
     */
    static of<A>(...elements: A[]): ArrayBuffer<A>;
    /**
     * Creates a new ArrayBuffer from an iterable.
     */
    static from<A>(iterable: Iterable$1<A>): ArrayBuffer<A>;
    /**
     * Creates an empty ArrayBuffer.
     */
    static empty<A>(): ArrayBuffer<A>;
    /**
     * Returns an iterator over the elements of this buffer.
     */
    iterator(): Iterator<A>;
    /**
     * Returns the element at the specified index.
     */
    apply(i: number): A;
    /**
     * Updates the element at the given index.
     */
    update(index: number, elem: A): void;
    /**
     * Returns the size of this buffer.
     */
    size(): number;
    /**
     * Returns the known size of this buffer.
     */
    knownSize(): number;
    /**
     * Transforms all elements of this buffer in place.
     */
    mapInPlace(f: (a: A) => A): this;
    /**
     * Sorts this buffer in place.
     */
    sortInPlace(implicit?: (a: A, b: A) => number): this;
    /**
     * Sorts this buffer in place according to a comparison function.
     */
    sortInPlaceWith(lt: (a: A, b: A) => boolean): this;
    /**
     * Sorts this buffer in place according to a key function.
     */
    sortInPlaceBy<B>(f: (a: A) => B, implicit?: (a: B, b: B) => number): this;
    /**
     * Appends an element to this buffer.
     */
    append(elem: A): this;
    /**
     * Appends all elements of a collection to this buffer.
     */
    appendAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Prepends an element to this buffer.
     */
    prepend(elem: A): this;
    /**
     * Prepends all elements of a collection to this buffer.
     */
    prependAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Inserts an element at a given index.
     */
    insert(idx: number, elem: A): this;
    /**
     * Inserts elements at a given index.
     */
    insertAll<B extends A>(idx: number, xs: Iterable$1<B>): this;
    /**
     * Pads this buffer to a given length by appending a value.
     */
    padToInPlace(len: number, elem: A): this;
    /**
     * Removes an element from this buffer.
     */
    subtractOne(elem: A): this;
    /**
     * Removes all elements in a collection from this buffer.
     */
    subtractAll<B extends A>(xs: Iterable$1<B>): this;
    /**
     * Removes the element at a given index.
     */
    remove(idx: number, count?: number): A;
    /**
     * Removes the first n elements.
     */
    trimStart(n: number): this;
    /**
     * Removes the last n elements.
     */
    trimEnd(n: number): this;
    /**
     * Removes all elements from this buffer.
     */
    clear(): this;
    /**
     * Replaces a slice of this buffer with another sequence.
     */
    patchInPlace<B extends A>(from: number, patch: Iterable$1<B>, replaced: number): this;
    /**
     * Returns a new buffer with the same elements as this buffer.
     */
    clone(): Buffer<A>;
    /**
     * Returns a new sequence with an element prepended.
     */
    prepended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements prepended.
     */
    prependedAll<B>(prefix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with an element appended.
     */
    appended(elem: A): Seq<A>;
    /**
     * Returns a new sequence with elements appended.
     */
    appendedAll<B>(suffix: Iterable$1<B>): Seq<A | B>;
    /**
     * Returns a new sequence with a slice of another sequence patched in.
     */
    patch<B>(from: number, patch: Seq<B>, replaced: number): Seq<A | B>;
    /**
     * Returns a new sequence with one element replaced.
     */
    updated(index: number, elem: A): Seq<A>;
    /**
     * Helper method to create a sequence from an array.
     */
    protected fromArray(arr: A[]): Seq<A>;
}

/**
 * Implementation of Scala-like LazyList, a lazy collection that evaluates elements only when needed.
 *
 * @example
 * ```ts
 * import { LazyList } from '@chris5855/scats';
 *
 * // Creating an infinite stream of numbers
 * const naturals = LazyList.from(0).map(n => n + 1);
 *
 * // Taking only the first 5 elements
 * const firstFive = naturals.take(5).toArray(); // [1, 2, 3, 4, 5]
 * ```
 * @module
 */

/**
 * A state of LazyList that is either empty or contains a head value and a tail LazyList.
 */
type State$1<A> = Empty | Cons<A>;
/**
 * Represents an empty LazyList.
 */
declare class Empty {
    readonly isEmpty = true;
}
/**
 * Represents a non-empty LazyList with a head element and a thunk that evaluates to the tail.
 */
declare class Cons<A> {
    readonly head: A;
    readonly tail: () => LazyList<A>;
    readonly isEmpty = false;
    constructor(head: A, tail: () => LazyList<A>);
}
/**
 * LazyList is an immutable, lazy evaluated sequence.
 * Elements are evaluated only when needed, making it efficient for representing
 * potentially infinite sequences.
 */
declare class LazyList<A> {
    private readonly state;
    /**
     * Creates a new LazyList with the given state thunk.
     */
    private constructor();
    /**
     * Returns whether this LazyList is empty.
     */
    isEmpty(): boolean;
    /**
     * Returns the first element of this LazyList, or None if it's empty.
     */
    headOption(): Option<A>;
    /**
     * Returns the first element of this LazyList.
     * @throws Error if the LazyList is empty
     */
    head(): A;
    /**
     * Returns the tail of this LazyList, or an empty LazyList if it's empty.
     */
    tail(): LazyList<A>;
    /**
     * Takes the first n elements of this LazyList.
     */
    take(n: number): LazyList<A>;
    /**
     * Skips the first n elements of this LazyList.
     */
    drop(n: number): LazyList<A>;
    /**
     * Maps each element of this LazyList using the provided function.
     */
    map<B>(f: (a: A) => B): LazyList<B>;
    /**
     * Applies the given function to each element and concatenates the results.
     * Uses a safe implementation to prevent stack overflows.
     */
    flatMap<B>(f: (a: A) => LazyList<B>): LazyList<B>;
    /**
     * Filters elements of this LazyList using the provided predicate.
     * Uses a non-recursive approach to prevent stack overflows.
     */
    filter(p: (a: A) => boolean): LazyList<A>;
    /**
     * Folds this LazyList from left to right using the provided function.
     */
    foldLeft<B>(z: B, f: (b: B, a: A) => B): B;
    /**
     * Converts this LazyList to an array.
     * This will force the evaluation of all elements.
     * Limits the maximum number of elements to prevent array length errors.
     */
    toArray(): A[];
    /**
     * Returns a LazyList consisting of the results of applying
     * the given function to the elements of this LazyList.
     */
    static map<A, B>(la: LazyList<A>, f: (a: A) => B): LazyList<B>;
    /**
     * Creates a LazyList containing the given elements.
     */
    static of<A>(...elements: A[]): LazyList<A>;
    /**
     * Creates an empty LazyList.
     */
    static empty<A>(): LazyList<A>;
    /**
     * Creates a LazyList with the given head and tail.
     */
    static cons<A>(head: A, tail: () => LazyList<A>): LazyList<A>;
    /**
     * Suspends a state computation in a thunk.
     */
    static suspend<A>(state: () => State$1<A>): LazyList<A>;
    /**
     * Creates a LazyList from an iterable source (array, Set, or other iterable).
     * If a single value is provided that's not an iterable, a single-element LazyList is returned.
     * @param iterable A value that can be iterated over, or a single value
     */
    static from<A>(iterable: A | A[] | Iterable<A>): LazyList<A>;
    /**
     * Creates a range of numbers from start (inclusive) to end (exclusive).
     * If no end is provided, creates a range from start to MAX_SAFE_RANGE.
     * @param start The start of the range (inclusive)
     * @param end The end of the range (exclusive). If undefined, creates a finite range up to MAX_SAFE_RANGE
     * @param step The step size
     */
    static range(start: number, end?: number, step?: number): LazyList<number>;
    /**
     * Creates a finite LazyList by repeated application of a function.
     * @param seed The initial value
     * @param f The function to apply to generate the next value
     * @param maxSize Maximum number of elements to generate (default 1000)
     */
    static iterate<A>(seed: A, f: (a: A) => A, maxSize?: number): LazyList<A>;
    /**
     * Creates a finite LazyList that repeatedly applies f.
     * @param f The function to apply
     * @param maxSize Maximum number of elements to generate (default 1000)
     */
    static continually<A>(f: () => A, maxSize?: number): LazyList<A>;
    /**
     * Applies a function to each element to create a new LazyList by iterating.
     * This is an instance method that allows chaining from a single value LazyList.
     * @param f The function to apply to generate next values
     */
    iterate(f: (a: A) => A): LazyList<A>;
}

/**
 * Implementation of Scala-like Vector, an efficient immutable indexed sequence.
 *
 * This is a trie-based implementation with a branching factor of 32, similar to
 * Scala's Vector. It provides efficient random access and updates while
 * maintaining immutability.
 *
 * @example
 * ```ts
 * import { Vector } from 'scats/vector';
 *
 * const vec = Vector.of(1, 2, 3, 4, 5);
 * const doubled = vec.map(x => x * 2);      // Vector(2, 4, 6, 8, 10)
 * const appended = vec.appended(6);          // Vector(1, 2, 3, 4, 5, 6)
 * const updated = vec.updated(2, 10);        // Vector(1, 2, 10, 4, 5)
 * ```
 */

/**
 * Vector is an immutable, indexed sequence optimized for fast random access
 * and updates. It provides efficient access to any element and good performance
 * for most operations.
 */
declare class Vector<A> {
    private readonly data;
    /**
     * Private constructor for creating a Vector from array data.
     * Use static methods like empty(), of(), from() to create vectors.
     */
    private constructor();
    /**
     * Returns the number of elements in this Vector.
     */
    size(): number;
    /**
     * Returns whether this Vector is empty.
     */
    isEmpty(): boolean;
    /**
     * Returns the element at the specified index.
     * @throws {Error} If the index is out of bounds.
     */
    apply(index: number): A;
    /**
     * Returns the element at the specified index, or None if the index is out of bounds.
     */
    get(index: number): Option<A>;
    /**
     * Returns a new Vector with the element at the specified index updated.
     * If the index is out of bounds, returns this Vector unchanged.
     */
    updated(index: number, elem: A): Vector<A>;
    /**
     * Returns a new Vector with the specified element appended.
     */
    appended(elem: A): Vector<A>;
    /**
     * Returns a new Vector with the specified element prepended.
     */
    prepended(elem: A): Vector<A>;
    /**
     * Returns a new Vector with all elements of the specified Vector appended.
     */
    appendAll<B>(that: Vector<B>): Vector<A | B>;
    /**
     * Maps each element of this Vector using the provided function.
     */
    map<B>(f: (a: A) => B): Vector<B>;
    /**
     * Applies the given function to each element and concatenates the results.
     */
    flatMap<B>(f: (a: A) => Vector<B>): Vector<B>;
    /**
     * Filters elements of this Vector using the provided predicate.
     */
    filter(p: (a: A) => boolean): Vector<A>;
    /**
     * Converts this Vector to an array.
     */
    toArray(): A[];
    /**
     * Creates a Vector containing the given elements.
     */
    static of<A>(...elements: A[]): Vector<A>;
    /**
     * Creates an empty Vector.
     */
    static empty<A>(): Vector<A>;
    /**
     * Creates a Vector from an array.
     */
    static from<A>(array: A[]): Vector<A>;
}

/**
 * Pattern matching implementation inspired by Scala's match expressions.
 * This module provides a way to match values against patterns and extract parts of them.
 *
 * @example
 * ```ts
 * import { match, when, otherwise } from 'scats';
 *
 * // Simple value matching
 * const result = match(value)
 *   .with(1, () => "one")
 *   .with(2, () => "two")
 *   .with(3, () => "three")
 *   .otherwise(() => "other");
 *
 * // Type matching with Option
 * const optRes = match(opt)
 *   .when(Some, (some) => `Value: ${some.get()}`)
 *   .when(None, () => "No value")
 *   .run();
 *
 * // Pattern matching with extractors
 * const person = { name: "John", age: 30 };
 * const greeting = match(person)
 *   .with({ name: "John", age: when((a) => a > 18) }, () => "Hello Mr. John")
 *   .with({ name: "John" }, () => "Hello John")
 *   .otherwise(() => "Hello stranger");
 * ```
 */
type Constructor<T> = new (...args: any[]) => T;
type TypePredicate<T> = (value: any) => value is T;
type PredicateFunction<T> = (value: T) => boolean;
type ExtractorFunction<T, R> = (value: T) => R;
/**
 * Represents a pattern that can be matched against a value
 */
interface Pattern<T, R = T> {
    match(value: any): {
        matched: boolean;
        extracted?: R;
    };
}
/**
 * Represents a match expression
 */
declare class MatchExpression<T, R> {
    private readonly value;
    private cases;
    private otherwiseHandler;
    constructor(value: T);
    /**
     * Adds a case with the provided pattern and handler
     */
    with<P>(pattern: P | Pattern<T>, handler: (value: P extends Pattern<T, infer X> ? X : T) => R): MatchExpression<T, R>;
    /**
     * Adds a case that matches if the value is of the provided type
     */
    when<P>(typeCheck: Constructor<P> | TypePredicate<P>, handler: (value: P) => R): MatchExpression<T, R>;
    /**
     * Adds a default case that matches if no other case matches
     */
    otherwise(handler: (value: T) => R): MatchExpression<T, R>;
    /**
     * Runs the match expression and returns the result
     */
    run(): R;
}
/**
 * Creates a match expression for the provided value
 */
declare function match<T, R = any>(value: T): MatchExpression<T, R>;
/**
 * Creates a pattern that matches if the value satisfies the provided predicate
 */
declare function when<T>(predicate: PredicateFunction<T>): Pattern<T>;
/**
 * Creates a pattern that always matches
 */
declare function otherwise<T>(): Pattern<T>;
/**
 * Creates a pattern that extracts a value using the provided extractor function
 */
declare function extract<T, R>(extractor: ExtractorFunction<T, R>): Pattern<T, R>;
/**
 * Creates a pattern that matches if the value equals the provided value
 */
declare function value<T>(expected: T): Pattern<T>;
/**
 * Creates a pattern that matches an object with the provided properties
 */
declare function object<T extends object>(pattern: Partial<{
    [K in keyof T]: Pattern<T[K]> | T[K];
}>): Pattern<T>;
/**
 * Creates a pattern that matches an array with the provided elements
 */
declare function array<T>(patterns: (Pattern<T> | T)[]): Pattern<T[]>;
/**
 * Creates a pattern that matches if any of the provided patterns match
 */
declare function or<T>(...patterns: Pattern<T>[]): Pattern<T>;
/**
 * Creates a pattern that matches if all of the provided patterns match
 */
declare function and<T>(...patterns: Pattern<T>[]): Pattern<T>;
/**
 * Creates a pattern that matches if the provided pattern does not match
 */
declare function not<T>(pattern: Pattern<T>): Pattern<T>;
/**
 * Creates a pattern that matches if the value is of the provided type
 */
declare function type<T>(typeCheck: Constructor<T> | TypePredicate<T>): Pattern<T>;

/**
 * For-comprehension implementation inspired by Scala's for expressions.
 * This module provides a way to sequence monadic operations in a readable way,
 * similar to how `async/await` works for Promises, but for any monad.
 *
 * @example
 * ```ts
 * import { For, Some, None, Option, List } from 'scats';
 *
 * // Using for-comprehension with Options
 * const result = For.of<Option<number>>()
 *   .bind('a', () => Some(1))
 *   .bind('b', ({ a }) => Some(a + 1))
 *   .bind('c', ({ a, b }) => Some(a + b))
 *   .yield(({ a, b, c }) => a + b + c);  // Some(6)
 *
 * // Early return if any step returns None
 * const noResult = For.of<Option<number>>()
 *   .bind('a', () => Some(1))
 *   .bind('b', ({ a }) => None)
 *   .bind('c', ({ a, b }) => Some(a + b))
 *   .yield(({ a, b, c }) => a + b + c);  // None
 *
 * // Using for-comprehension with Lists
 * const cartesianProduct = For.of<List<[number, string]>>()
 *   .bind('a', () => List.of(1, 2, 3))
 *   .bind('b', () => List.of('x', 'y'))
 *   .yield(({ a, b }) => [a, b] as [number, string]);  // List([1, 'x'], [1, 'y'], [2, 'x'], [2, 'y'], [3, 'x'], [3, 'y'])
 * ```
 */

/**
 * An interface that represents monads with map and flatMap operations
 */
interface Monad<A> {
    map<B>(f: (a: A) => B): Monad<B>;
    flatMap<B>(f: (a: A) => Monad<B>): Monad<B>;
}
/**
 * Type for the environment object in for-comprehension
 */
type Env = Record<string, any>;
/**
 * A monadic context that accumulates bindings for for-comprehension
 */
declare class ForComprehension<M, T extends Env = {}> {
    private readonly pure;
    private readonly flatMap;
    private readonly value;
    constructor(pure: <A>(a: A) => M, flatMap: <A>(ma: M, f: (a: A) => M) => M, value?: M);
    /**
     * Binds a new value to the given name in the environment
     */
    bind<K extends string, A>(name: K, f: (env: T) => M): ForComprehension<M, T & Record<K, A>>;
    /**
     * Adds a filter condition to the for-comprehension
     */
    filter(predicate: (env: T) => boolean): ForComprehension<M, T>;
    /**
     * Yields a final result from the for-comprehension
     */
    yield<R>(f: (env: T) => R): M;
    /**
     * Returns an empty value for the given monad
     */
    private empty;
    /**
     * Checks if the monad is an Option
     */
    private isOptionMonad;
    /**
     * Checks if the monad is a List
     */
    private isListMonad;
}
/**
 * Factory for creating for-comprehensions for different monads
 */
declare namespace For {
    /**
     * Creates a for-comprehension for Option
     */
    function option<T extends Env = {}>(): ForComprehension<Option<any>, T>;
    /**
     * Creates a for-comprehension for Either
     */
    function either<E, T extends Env = {}>(): ForComprehension<Either<E, any>, T>;
    /**
     * Creates a for-comprehension for List
     */
    function list<T extends Env = {}>(): ForComprehension<List<any>, T>;
    /**
     * Creates a for-comprehension for Try
     */
    function tryM<T extends Env = {}>(): ForComprehension<Try<any>, T>;
    /**
     * Creates a generic for-comprehension for any monad
     */
    function of<M, T extends Env = {}>(): ForComprehensionBuilder<M, T>;
}
/**
 * Builder for creating for-comprehensions
 */
declare class ForComprehensionBuilder<M, T extends Env = {}> {
    /**
     * Creates a for-comprehension for Option
     */
    option(): ForComprehension<Option<any>, T>;
    /**
     * Creates a for-comprehension for Either
     */
    either<E>(): ForComprehension<Either<E, any>, T>;
    /**
     * Creates a for-comprehension for List
     */
    list(): ForComprehension<List<any>, T>;
    /**
     * Creates a for-comprehension for Try
     */
    tryM(): ForComprehension<Try<any>, T>;
    /**
     * Creates a for-comprehension for a custom monad
     */
    custom(pure: <X>(b: X) => M, flatMap: <X>(mb: M, f: (b: X) => M) => M): ForComprehension<M, T>;
}

/**
 * Type class implementation that provides a way to add functionality to existing types.
 * This module enables ad-hoc polymorphism and interface extension through a pattern
 * similar to Scala's implicits and type classes.
 *
 * @example
 * ```ts
 * import { TypeClass, TypeClassRegistry } from 'scats';
 *
 * // Define a type class
 * interface Numeric<T> {
 *   add(a: T, b: T): T;
 *   zero(): T;
 *   fromNumber(n: number): T;
 * }
 *
 * // Create a registry for the Numeric type class
 * const NumericRegistry = new TypeClassRegistry<Numeric<any>>();
 *
 * // Register an instance for the number type
 * NumericRegistry.register<number>({
 *   add: (a, b) => a + b,
 *   zero: () => 0,
 *   fromNumber: n => n
 * });
 *
 * // Register an instance for the string type
 * NumericRegistry.register<string>({
 *   add: (a, b) => a + b,
 *   zero: () => "",
 *   fromNumber: n => n.toString()
 * });
 *
 * // Use the type class
 * function sum<T>(values: T[], numeric: Numeric<T>): T {
 *   return values.reduce((acc, val) => numeric.add(acc, val), numeric.zero());
 * }
 *
 * // Automatically resolving type class instances
 * function sumWith<T>(values: T[]): T {
 *   const numeric = NumericRegistry.get<T>();
 *   return sum(values, numeric);
 * }
 * ```
 */
/**
 * Base interface for type classes
 */
interface TypeClass<T> {
    readonly __type?: T;
}
/**
 * Registry for type class instances
 */
declare class TypeClassRegistry<TC extends TypeClass<any>> {
    private readonly instances;
    /**
     * Registers a type class instance for a specific type
     */
    register<T>(instance: TC & TypeClass<T>, type?: {
        new (...args: any[]): T;
    }): void;
    /**
     * Gets a type class instance for a specific type
     * @throws Error if no instance is found
     */
    get<T>(): TC & TypeClass<T>;
    /**
     * Gets a type class instance for a specific value
     * @throws Error if no instance is found
     */
    getFor<T>(value: T): TC & TypeClass<T>;
    /**
     * Checks if an instance exists for a specific type
     */
    has<T>(type: {
        new (...args: any[]): T;
    }): boolean;
    /**
     * Checks if an instance exists for a specific value
     */
    hasFor<T>(value: T): boolean;
    /**
     * Gets a type key for a type class instance
     */
    private typeKey;
    /**
     * Checks if a value is an instance of a type
     */
    private isInstanceOf;
}
/**
 * Decorator for registering type class instances
 */
declare function register<TC extends TypeClass<any>>(registry: TypeClassRegistry<TC>): <T extends TC>(target: T) => void;
/**
 * Extension method factory for type classes
 */
declare function extension<T, TC extends TypeClass<T>>(registry: TypeClassRegistry<TC>, getForValue: (value: any) => T): <K extends keyof TC>(methodName: K) => (...args: any[]) => any;
/**
 * Context bound implementation that allows using type classes with a specific type
 */
declare function withContext<T, TC extends TypeClass<T>>(registry: TypeClassRegistry<TC>, action: (instance: TC) => void): void;
/**
 * A registry for all type classes
 */
declare const GlobalTypeClassRegistry: TypeClassRegistry<TypeClass<any>>;

/**
 * Implementation of Scala-like Tuples
 *
 * @example
 * ```ts
 * import { Tuple, Tuple2 } from 'scats/tuple';
 *
 * const pair = Tuple.of(1, "hello");
 * const first = pair._1;  // 1
 * const swapped = pair.swap();  // Tuple2("hello", 1)
 *
 * // Destructuring
 * const [num, str] = pair;
 *
 * // Creating a tuple of 3 elements
 * const triple = Tuple.of(1, "hello", true);
 * ```
 */
/**
 * Tuple2 represents an ordered pair of values.
 */
declare class Tuple2<T1, T2> implements Iterable<T1 | T2> {
    readonly _1: T1;
    readonly _2: T2;
    /**
     * Creates a new Tuple2 with the given values.
     */
    constructor(_1: T1, _2: T2);
    /**
     * Returns a new Tuple2 with the elements swapped.
     */
    swap(): Tuple2<T2, T1>;
    /**
     * Maps the first element of this Tuple2 using the provided function.
     */
    map1<U>(f: (value: T1) => U): Tuple2<U, T2>;
    /**
     * Maps the second element of this Tuple2 using the provided function.
     */
    map2<U>(f: (value: T2) => U): Tuple2<T1, U>;
    /**
     * Maps both elements of this Tuple2 using the provided functions.
     */
    bimap<U1, U2>(f1: (value: T1) => U1, f2: (value: T2) => U2): Tuple2<U1, U2>;
    /**
     * Converts this Tuple2 to an array.
     */
    toArray(): [T1, T2];
    /**
     * Returns a string representation of this Tuple2.
     */
    toString(): string;
    /**
     * Returns an iterator over the elements of this Tuple2.
     */
    [Symbol.iterator](): Iterator<T1 | T2>;
}
/**
 * Tuple3 represents an ordered triplet of values.
 */
declare class Tuple3<T1, T2, T3> implements Iterable<T1 | T2 | T3> {
    readonly _1: T1;
    readonly _2: T2;
    readonly _3: T3;
    /**
     * Creates a new Tuple3 with the given values.
     */
    constructor(_1: T1, _2: T2, _3: T3);
    /**
     * Maps the first element of this Tuple3 using the provided function.
     */
    map1<U>(f: (value: T1) => U): Tuple3<U, T2, T3>;
    /**
     * Maps the second element of this Tuple3 using the provided function.
     */
    map2<U>(f: (value: T2) => U): Tuple3<T1, U, T3>;
    /**
     * Maps the third element of this Tuple3 using the provided function.
     */
    map3<U>(f: (value: T3) => U): Tuple3<T1, T2, U>;
    /**
     * Maps all elements of this Tuple3 using the provided functions.
     */
    map<U1, U2, U3>(f1: (value: T1) => U1, f2: (value: T2) => U2, f3: (value: T3) => U3): Tuple3<U1, U2, U3>;
    /**
     * Converts this Tuple3 to a Tuple2 by removing the third element.
     */
    toTuple2(): Tuple2<T1, T2>;
    /**
     * Converts this Tuple3 to an array.
     */
    toArray(): [T1, T2, T3];
    /**
     * Returns a string representation of this Tuple3.
     */
    toString(): string;
    /**
     * Returns an iterator over the elements of this Tuple3.
     */
    [Symbol.iterator](): Iterator<T1 | T2 | T3>;
}
/**
 * Tuple namespace containing utility functions for creating tuples.
 */
declare const Tuple: {
    /**
     * Creates a tuple from the given values.
     */
    of(...values: any[]): any;
    /**
     * Creates a Tuple2 from an array with two elements.
     */
    fromArray2<T1, T2>(array: [T1, T2]): Tuple2<T1, T2>;
    /**
     * Creates a Tuple3 from an array with three elements.
     */
    fromArray3<T1, T2, T3>(array: [T1, T2, T3]): Tuple3<T1, T2, T3>;
    /**
     * Creates a Tuple2 from an entry (key-value pair).
     */
    fromEntry<K, V>(entry: [K, V]): Tuple2<K, V>;
};

/**
 * Abstract base class for implementing the Ordering interface.
 */
declare abstract class AbstractOrdering<T> implements Ordering<T> {
    abstract compare(x: T, y: T): number;
    lt(x: T, y: T): boolean;
    lte(x: T, y: T): boolean;
    gt(x: T, y: T): boolean;
    gte(x: T, y: T): boolean;
    equals(x: T, y: T): boolean;
    min(x: T, y: T): T;
    max(x: T, y: T): T;
    reverse(): Ordering<T>;
    andThen<U extends T>(that: Ordering<U>): Ordering<U>;
}
/**
 * Ordering instance for numbers.
 */
declare class NumberOrdering extends AbstractOrdering<number> {
    compare(x: number, y: number): number;
}
/**
 * Ordering instance for strings.
 */
declare class StringOrdering extends AbstractOrdering<string> {
    compare(x: string, y: string): number;
}
/**
 * Ordering instance for booleans.
 */
declare class BooleanOrdering extends AbstractOrdering<boolean> {
    compare(x: boolean, y: boolean): number;
}
/**
 * Ordering instance for dates.
 */
declare class DateOrdering extends AbstractOrdering<Date> {
    compare(x: Date, y: Date): number;
}
/**
 * Implementation of Scala-like Ordering type class for comparison operations.
 *
 * @example
 * ```ts
 * import { Ordering } from 'scats/ordering';
 *
 * // Using built-in orderings
 * const numbers = [3, 1, 4, 1, 5, 9];
 * const sorted = numbers.sort(Ordering.number.compare);
 *
 * // Creating a custom ordering
 * const personOrdering = Ordering.by<Person, string>(p => p.name);
 * const sortedPeople = people.sort(personOrdering.compare);
 *
 * // Reverse ordering
 * const descendingOrder = Ordering.number.reverse();
 * const sortedDesc = numbers.sort(descendingOrder.compare);
 * ```
 */
/**
 * Ordering is a type class for objects that can be compared.
 */
interface Ordering<T> {
    /**
     * Compares two values.
     *
     * Returns a negative number if x < y, zero if x = y, and a positive number if x > y.
     */
    compare(x: T, y: T): number;
    /**
     * Returns true if x < y.
     */
    lt(x: T, y: T): boolean;
    /**
     * Returns true if x <= y.
     */
    lte(x: T, y: T): boolean;
    /**
     * Returns true if x > y.
     */
    gt(x: T, y: T): boolean;
    /**
     * Returns true if x >= y.
     */
    gte(x: T, y: T): boolean;
    /**
     * Returns true if x = y.
     */
    equals(x: T, y: T): boolean;
    /**
     * Returns the minimum of two values.
     */
    min(x: T, y: T): T;
    /**
     * Returns the maximum of two values.
     */
    max(x: T, y: T): T;
    /**
     * Returns a new Ordering that compares in the reverse order.
     */
    reverse(): Ordering<T>;
    /**
     * Returns a new Ordering that first compares using this ordering, and if that
     * comparison is zero, then compares using the given ordering.
     */
    andThen<U extends T>(that: Ordering<U>): Ordering<U>;
}
/**
 * Ordering namespace containing utility functions and predefined orderings.
 */
declare const Ordering: {
    /**
     * Ordering for numbers.
     */
    number: NumberOrdering;
    /**
     * Ordering for strings.
     */
    string: StringOrdering;
    /**
     * Ordering for booleans.
     */
    boolean: BooleanOrdering;
    /**
     * Ordering for dates.
     */
    date: DateOrdering;
    /**
     * Creates a new Ordering by mapping the values to a type with a defined ordering.
     */
    by<T, U>(f: (t: T) => U, ordering?: Ordering<U>): Ordering<T>;
    /**
     * Creates a natural ordering for the given type.
     *
     * This assumes the type has a natural ordering (e.g., numbers, strings, dates).
     */
    natural<T>(): Ordering<T>;
};

/**
 * Implementation of Scala-like resource management utilities (Using/Auto-Closeable).
 *
 * @example
 * ```ts
 * import { Using } from 'scats/using';
 *
 * // Create a resource that needs to be closed
 * class Resource implements Closeable {
 *   constructor(readonly id: string) {
 *     console.log(`Resource ${id} created`);
 *   }
 *
 *   getData(): string {
 *     return `Data from resource ${this.id}`;
 *   }
 *
 *   close(): void {
 *     console.log(`Resource ${this.id} closed`);
 *   }
 * }
 *
 * // Use the resource and ensure it gets closed
 * const result = Using.resource(new Resource("123"), (resource) => {
 *   return resource.getData().toUpperCase();
 * });
 *
 * // Use multiple resources
 * const result2 = Using.resources(
 *   [new Resource("A"), new Resource("B")],
 *   ([resourceA, resourceB]) => {
 *     return resourceA.getData() + " + " + resourceB.getData();
 *   }
 * );
 * ```
 */

/**
 * Interface for resources that can be closed or released.
 */
interface Closeable {
    /**
     * Closes or releases the resource.
     */
    close(): void;
}
/**
 * Using is a utility class for working with resources that need
 * to be closed or released after use, like files or database connections.
 */
declare const Using: {
    /**
     * Use a resource and ensure it is closed, even if an exception occurs.
     *
     * @param resource The resource to use
     * @param f The function to apply to the resource
     * @returns The result of applying f to the resource
     */
    resource<R extends Closeable, A>(resource: R, f: (r: R) => A): Try<A>;
    /**
     * Use multiple resources and ensure they are all closed, even if an exception occurs.
     *
     * @param resources The resources to use
     * @param f The function to apply to the resources
     * @returns The result of applying f to the resources
     */
    resources<R extends Closeable, A>(resources: R[], f: (rs: R[]) => A): Try<A>;
    /**
     * Use a resource asynchronously and ensure it is closed, even if an exception occurs.
     *
     * @param resource The resource to use
     * @param f The function to apply to the resource
     * @returns A promise that resolves to the result of applying f to the resource
     */
    resourceAsync<R extends Closeable, A>(resource: R, f: (r: R) => Promise<A>): Promise<A>;
    /**
     * Use multiple resources asynchronously and ensure they are all closed, even if an exception occurs.
     *
     * @param resources The resources to use
     * @param f The function to apply to the resources
     * @returns A promise that resolves to the result of applying f to the resources
     */
    resourcesAsync<R extends Closeable, A>(resources: R[], f: (rs: R[]) => Promise<A>): Promise<A>;
    /**
     * Creates a resource manager that can be used with a 'with' pattern.
     *
     * @param acquire Function to acquire the resource
     * @param release Function to release the resource
     * @returns A resource manager
     */
    manager<R, A>(acquire: () => R, release: (r: R) => void): {
        use: <A_1>(f: (r: R) => A_1) => A_1;
        useAsync: <A_1>(f: (r: R) => Promise<A_1>) => Promise<A_1>;
    };
};

/**
 * Implementation of the State monad for functional state management.
 *
 * @example
 * ```ts
 * import { State } from 'scats/monads/state';
 *
 * // Define a state type
 * type GameState = {
 *   score: number;
 *   level: number;
 * };
 *
 * // Create operations on the state
 * const incrementScore = (points: number) => State.modify<GameState>(state => ({
 *   ...state,
 *   score: state.score + points
 * }));
 *
 * const levelUp = State.modify<GameState>(state => ({
 *   ...state,
 *   level: state.level + 1
 * }));
 *
 * const getScore = State.gets<GameState, number>(state => state.score);
 *
 * // Combine operations
 * const playGame = State.sequence([
 *   incrementScore(100),
 *   incrementScore(50),
 *   levelUp,
 *   getScore
 * ]);
 *
 * // Run the state computation
 * const initialState: GameState = { score: 0, level: 1 };
 * const [finalScore, finalState] = playGame.run(initialState);
 *
 * console.log(finalScore);   // 150
 * console.log(finalState);   // { score: 150, level: 2 }
 * ```
 */
/**
 * The State monad represents a computation that can read and write a state value.
 *
 * Example:
 * ```
 * // Define a game state
 * interface GameState {
 *   score: number;
 *   level: number;
 * }
 *
 * // Create state operations
 * const incrementScore = (points: number) =>
 *   State.modify<GameState>(state => ({...state, score: state.score + points}));
 *
 * const levelUp = State.modify<GameState>(state => ({...state, level: state.level + 1}));
 *
 * // Combine operations
 * const winLevel = (points: number) =>
 *   incrementScore(points).flatMap(() => levelUp);
 *
 * // Run the computation
 * const initialState: GameState = { score: 0, level: 1 };
 * const [_, newState] = winLevel(100).run(initialState);
 * // newState is { score: 100, level: 2 }
 * ```
 */
declare class StateMonad<S, A> {
    readonly runState: (s: S) => [A, S];
    /**
     * Creates a new State.
     */
    constructor(runState: (s: S) => [A, S]);
    /**
     * Runs this state computation with the given initial state.
     */
    run(initialState: S): [A, S];
    /**
     * Executes this state computation and returns the final value.
     */
    eval(initialState: S): A;
    /**
     * Executes this state computation and returns the final state.
     */
    exec(initialState: S): S;
    /**
     * Maps the result of this state computation using the given function.
     */
    map<B>(f: (a: A) => B): StateMonad<S, B>;
    /**
     * Returns a state computation that applies the function produced by this
     * state computation to the result of another state computation.
     */
    ap<B>(sf: StateMonad<S, (a: A) => B>): StateMonad<S, B>;
    /**
     * Chains this state computation with another one.
     */
    flatMap<B>(f: (a: A) => StateMonad<S, B>): StateMonad<S, B>;
    /**
     * Alias for flatMap.
     */
    chain<B>(f: (a: A) => StateMonad<S, B>): StateMonad<S, B>;
    /**
     * Transforms both the result and the state using the given functions.
     */
    bimap<B, T>(f: (a: A) => B, g: (s: S) => T): StateMonad<T, B>;
}
/**
 * State monad utilities and constructors
 */
declare const State: {
    /**
     * Creates a new State computation that returns the given value without modifying the state.
     */
    of<S, A>(a: A): StateMonad<S, A>;
    /**
     * Creates a new State computation that returns the current state.
     */
    get<S>(): StateMonad<S, S>;
    /**
     * Creates a new State computation that replaces the state with a new value.
     */
    put<S>(newState: S): StateMonad<S, void>;
    /**
     * Creates a new State computation that modifies the state using the given function.
     */
    modify<S>(f: (s: S) => S): StateMonad<S, void>;
    /**
     * Creates a new State computation that returns a part of the state using the given function.
     */
    gets<S, A>(f: (s: S) => A): StateMonad<S, A>;
    /**
     * Combines multiple state computations into a single one that returns an array of results.
     */
    sequence<S, A>(states: StateMonad<S, A>[]): StateMonad<S, A[]>;
};
type State<S, A> = StateMonad<S, A>;

/**
 * The Writer monad represents a computation that produces a value along with a log.
 * It's useful for collecting log messages, building up computations with a log of changes, etc.
 *
 * Example:
 * ```
 * // Create a writer that logs some text and returns a value
 * const logNumber = (n: number) =>
 *   Writer.tell<string, number>(`Processing ${n}`).flatMap(() => Writer.of(n * 2), Monoids.string);
 *
 * // Run computations that accumulate logs
 * const result = logNumber(5)
 *   .flatMap(n => Writer.tell(`Result is ${n}`).flatMap(() => Writer.of(n), Monoids.string), Monoids.string);
 *
 * // Extract result and logs
 * const [value, logs] = result.run();
 * // value: 10, logs: "Processing 5Result is 10"
 * ```
 */
/**
 * Represents a semigroup that can be combined with another value of the same type.
 */
interface Semigroup<T> {
    concat(a: T, b: T): T;
}
/**
 * Represents a monoid, which is a semigroup with an identity element.
 */
interface Monoid<T> extends Semigroup<T> {
    empty(): T;
}
/**
 * A Writer monad implementation that produces a value along with a log.
 */
declare class WriterMonad<W, A> {
    private readonly value;
    private readonly log;
    constructor(value: A, log: W);
    /**
     * Runs this writer computation and returns the result value and log.
     */
    run(): [A, W];
    /**
     * Returns the value from this writer computation.
     */
    getValue(): A;
    /**
     * Returns the log from this writer computation.
     */
    getLog(): W;
    /**
     * Maps the result of this writer computation using the given function.
     */
    map<B>(f: (a: A) => B): WriterMonad<W, B>;
    /**
     * Chains this writer computation with another one.
     * The logs are combined using the provided monoid.
     */
    flatMap<B>(f: (a: A) => WriterMonad<W, B>, monoid: Monoid<W>): WriterMonad<W, B>;
    /**
     * Applies a function inside a writer to a value inside this writer.
     * The logs are combined using the provided monoid.
     */
    ap<B>(wf: WriterMonad<W, (a: A) => B>, monoid: Monoid<W>): WriterMonad<W, B>;
    /**
     * Maps both the value and the log using provided functions.
     */
    bimap<B, X>(f: (a: A) => B, g: (w: W) => X): WriterMonad<X, B>;
    /**
     * Maps the log using a provided function.
     */
    mapLog<X>(f: (w: W) => X): WriterMonad<X, A>;
}
/**
 * Commonly used monoids
 */
declare const Monoids: {
    /**
     * A monoid for strings, where concat is string concatenation.
     */
    string: {
        empty: () => string;
        concat: (a: string, b: string) => string;
    };
    /**
     * A monoid for arrays, where concat is array concatenation.
     */
    array<T>(): Monoid<T[]>;
};
/**
 * Writer monad utilities and constructors
 */
declare const Writer: {
    /**
     * Creates a new Writer that returns the given value with an empty log.
     */
    of<W, A>(value: A, monoid: Monoid<W>): WriterMonad<W, A>;
    /**
     * Creates a new Writer that adds the given log message with a default value.
     */
    tell<W, A = void>(log: W): WriterMonad<W, void>;
    /**
     * Creates a new Writer that returns the value of the given writer without its log.
     */
    listen<W, A>(w: WriterMonad<W, A>): WriterMonad<W, [A, W]>;
    /**
     * Creates a new Writer that passes both the value and log to a function to produce a new writer.
     */
    pass<W, A>(w: WriterMonad<W, [A, (w: W) => W]>): WriterMonad<W, A>;
    /**
     * Helper function to create a Writer with a string log.
     */
    withString<A>(value: A, log?: string): WriterMonad<string, A>;
    /**
     * Helper function to create a Writer with an array log.
     */
    withArray<W, A>(value: A, log?: W[]): WriterMonad<W[], A>;
};
/**
 * Type alias for convenience
 */
type Writer<W, A> = WriterMonad<W, A>;

export { AbstractIterable, ArrayBuffer, ArraySeq, type Buffer, type Closeable, Either, type Env, ExecutionContext, Failure, For, ForComprehension, ForComprehensionBuilder, GlobalTypeClassRegistry, type IndexedSeq, type Iterable$1 as Iterable, LazyList, Left, type LinearSeq, List, Map, type Monad, Monoids, type MutableIndexedSeq, None, Option, Ordering, type Pattern, Right, type Seq, Set, Some, State, StateMonad, Success, Try, TryAsync, Tuple, Tuple2, Tuple3, type TypeClass, TypeClassRegistry, Using, Vector, Writer, WriterMonad, and, array, extension, extract, match, not, object, or, otherwise, register, type, value, when, withContext };
