/**
 * This module provides utility functions for working with arrays in TypeScript.
 *
 * @since 2.0.0
 */
import type { Either } from "./Either.js";
import * as Equivalence from "./Equivalence.js";
import type { LazyArg } from "./Function.js";
import type { TypeLambda } from "./HKT.js";
import type { Option } from "./Option.js";
import * as Order from "./Order.js";
import type { Predicate, Refinement } from "./Predicate.js";
import * as Record from "./Record.js";
import type { NoInfer } from "./Types.js";
/**
 * @category type lambdas
 * @since 2.0.0
 */
export interface ReadonlyArrayTypeLambda extends TypeLambda {
    readonly type: ReadonlyArray<this["Target"]>;
}
/**
 * @category models
 * @since 2.0.0
 */
export type NonEmptyReadonlyArray<A> = readonly [A, ...Array<A>];
/**
 * @category models
 * @since 2.0.0
 */
export type NonEmptyArray<A> = [A, ...Array<A>];
/**
 * Builds a `NonEmptyArray` from an non-empty collection of elements.
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const make: <Elements extends [any, ...any[]]>(...elements: Elements) => [Elements[number], ...Elements[number][]];
/**
 * Creates a new `Array` of the specified length.
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const allocate: <A = never>(n: number) => Array<A | undefined>;
/**
 * Return a `NonEmptyArray` of length `n` with element `i` initialized with `f(i)`.
 *
 * **Note**. `n` is normalized to an integer >= 1.
 *
 * @example
 * import { makeBy } from "effect/Array"
 *
 * assert.deepStrictEqual(makeBy(5, n => n * 2), [0, 2, 4, 6, 8])
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const makeBy: <A>(n: number, f: (i: number) => A) => [A, ...A[]];
/**
 * Return a `NonEmptyArray` containing a range of integers, including both endpoints.
 *
 * @example
 * import { range } from "effect/Array"
 *
 * assert.deepStrictEqual(range(1, 3), [1, 2, 3])
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const range: (start: number, end: number) => [number, ...number[]];
/**
 * Return a `NonEmptyArray` containing a value repeated the specified number of times.
 *
 * **Note**. `n` is normalized to an integer >= 1.
 *
 * @example
 * import { replicate } from "effect/Array"
 *
 * assert.deepStrictEqual(replicate("a", 3), ["a", "a", "a"])
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const replicate: {
    (n: number): <A>(a: A) => NonEmptyArray<A>;
    <A>(a: A, n: number): NonEmptyArray<A>;
};
/**
 * Creates a new `Array` from an iterable collection of values.
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const fromIterable: <A>(collection: Iterable<A>) => Array<A>;
/**
 * Takes a record and returns an array of tuples containing its keys and values.
 *
 * @param self - The record to transform.
 *
 * @example
 * import { fromRecord } from "effect/Array"
 *
 * const x = { a: 1, b: 2, c: 3 }
 * assert.deepStrictEqual(fromRecord(x), [["a", 1], ["b", 2], ["c", 3]])
 *
 * @category conversions
 * @since 2.0.0
 */
export declare const fromRecord: <K extends string, A>(self: Readonly<Record<K, A>>) => Array<[K, A]>;
/**
 * @category conversions
 * @since 2.0.0
 */
export declare const fromOption: <A>(self: Option<A>) => Array<A>;
/**
 * @category pattern matching
 * @since 2.0.0
 */
export declare const match: {
    <B, A, C = B>(options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C;
    }): (self: ReadonlyArray<A>) => B | C;
    <A, B, C = B>(self: ReadonlyArray<A>, options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C;
    }): B | C;
};
/**
 * @category pattern matching
 * @since 2.0.0
 */
export declare const matchLeft: {
    <B, A, C = B>(options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (head: A, tail: Array<A>) => C;
    }): (self: ReadonlyArray<A>) => B | C;
    <A, B, C = B>(self: ReadonlyArray<A>, options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (head: A, tail: Array<A>) => C;
    }): B | C;
};
/**
 * @category pattern matching
 * @since 2.0.0
 */
export declare const matchRight: {
    <B, A, C = B>(options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (init: Array<A>, last: A) => C;
    }): (self: ReadonlyArray<A>) => B | C;
    <A, B, C = B>(self: ReadonlyArray<A>, options: {
        readonly onEmpty: LazyArg<B>;
        readonly onNonEmpty: (init: Array<A>, last: A) => C;
    }): B | C;
};
/**
 * Prepend an element to the front of an `Iterable`, creating a new `NonEmptyArray`.
 *
 * @category concatenating
 * @since 2.0.0
 */
export declare const prepend: {
    <B>(head: B): <A>(self: Iterable<A>) => NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, head: B): NonEmptyArray<A | B>;
};
/**
 * Prepends the specified prefix array (or iterable) to the beginning of the specified array (or iterable).
 * If either array is non-empty, the result is also a non-empty array.
 *
 * @example
 * import { Array } from "effect"
 *
 * assert.deepStrictEqual(
 *   Array.prependAll([1, 2], ["a", "b"]),
 *   ["a", "b", 1, 2]
 * )
 *
 * @category concatenating
 * @since 2.0.0
 */
export declare const prependAll: {
    <S extends ReadonlyArray<any> | Iterable<any>, T extends ReadonlyArray<any> | Iterable<any>>(that: T): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>;
    <A, B>(self: Iterable<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, that: Iterable<B>): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
};
/**
 * Append an element to the end of an `Iterable`, creating a new `NonEmptyArray`.
 *
 * @category concatenating
 * @since 2.0.0
 */
export declare const append: {
    <B>(last: B): <A>(self: Iterable<A>) => NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, last: B): NonEmptyArray<A | B>;
};
/**
 * Concatenates two arrays (or iterables), combining their elements.
 * If either array is non-empty, the result is also a non-empty array.
 *
 * @category concatenating
 * @since 2.0.0
 */
export declare const appendAll: {
    <S extends ReadonlyArray<any> | Iterable<any>, T extends ReadonlyArray<any> | Iterable<any>>(that: T): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>;
    <A, B>(self: Iterable<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, that: Iterable<B>): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
};
/**
 * Reduce an `Iterable` from the left, keeping all intermediate results instead of only the final result.
 *
 * @category folding
 * @since 2.0.0
 */
export declare const scan: {
    <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => NonEmptyArray<B>;
    <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B>;
};
/**
 * Reduce an `Iterable` from the right, keeping all intermediate results instead of only the final result.
 *
 * @category folding
 * @since 2.0.0
 */
export declare const scanRight: {
    <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => NonEmptyArray<B>;
    <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B>;
};
/**
 * Determine if `unknown` is an Array.
 *
 * @param self - The value to check.
 *
 * @example
 * import { isArray } from "effect/Array"
 *
 * assert.deepStrictEqual(isArray(null), false);
 * assert.deepStrictEqual(isArray([1, 2, 3]), true);
 *
 * @category guards
 * @since 2.0.0
 */
export declare const isArray: {
    (self: unknown): self is Array<unknown>;
    <T>(self: T): self is Extract<T, ReadonlyArray<any>>;
};
/**
 * Determine if an `Array` is empty narrowing down the type to `[]`.
 *
 * @param self - The `Array` to check.
 *
 * @example
 * import { isEmptyArray } from "effect/Array"
 *
 * assert.deepStrictEqual(isEmptyArray([]), true);
 * assert.deepStrictEqual(isEmptyArray([1, 2, 3]), false);
 *
 * @category guards
 * @since 2.0.0
 */
export declare const isEmptyArray: <A>(self: Array<A>) => self is [];
/**
 * Determine if a `ReadonlyArray` is empty narrowing down the type to `readonly []`.
 *
 * @param self - The `ReadonlyArray` to check.
 *
 * @example
 * import { isEmptyReadonlyArray } from "effect/Array"
 *
 * assert.deepStrictEqual(isEmptyReadonlyArray([]), true);
 * assert.deepStrictEqual(isEmptyReadonlyArray([1, 2, 3]), false);
 *
 * @category guards
 * @since 2.0.0
 */
export declare const isEmptyReadonlyArray: <A>(self: ReadonlyArray<A>) => self is readonly [];
/**
 * Determine if an `Array` is non empty narrowing down the type to `NonEmptyArray`.
 *
 * An `Array` is considered to be a `NonEmptyArray` if it contains at least one element.
 *
 * @param self - The `Array` to check.
 *
 * @example
 * import { isNonEmptyArray } from "effect/Array"
 *
 * assert.deepStrictEqual(isNonEmptyArray([]), false);
 * assert.deepStrictEqual(isNonEmptyArray([1, 2, 3]), true);
 *
 * @category guards
 * @since 2.0.0
 */
export declare const isNonEmptyArray: <A>(self: Array<A>) => self is NonEmptyArray<A>;
/**
 * Determine if a `ReadonlyArray` is non empty narrowing down the type to `NonEmptyReadonlyArray`.
 *
 * A `ReadonlyArray` is considered to be a `NonEmptyReadonlyArray` if it contains at least one element.
 *
 * @param self - The `ReadonlyArray` to check.
 *
 * @example
 * import { isNonEmptyReadonlyArray } from "effect/Array"
 *
 * assert.deepStrictEqual(isNonEmptyReadonlyArray([]), false);
 * assert.deepStrictEqual(isNonEmptyReadonlyArray([1, 2, 3]), true);
 *
 * @category guards
 * @since 2.0.0
 */
export declare const isNonEmptyReadonlyArray: <A>(self: ReadonlyArray<A>) => self is NonEmptyReadonlyArray<A>;
/**
 * Return the number of elements in a `ReadonlyArray`.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const length: <A>(self: ReadonlyArray<A>) => number;
/**
 * This function provides a safe way to read a value at a particular index from a `ReadonlyArray`.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const get: {
    (index: number): <A>(self: ReadonlyArray<A>) => Option<A>;
    <A>(self: ReadonlyArray<A>, index: number): Option<A>;
};
/**
 * Gets an element unsafely, will throw on out of bounds.
 *
 * @since 2.0.0
 * @category unsafe
 */
export declare const unsafeGet: {
    (index: number): <A>(self: ReadonlyArray<A>) => A;
    <A>(self: ReadonlyArray<A>, index: number): A;
};
/**
 * Return a tuple containing the first element, and a new `Array` of the remaining elements, if any.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const unprepend: <A>(self: readonly [A, ...A[]]) => [firstElement: A, remainingElements: Array<A>];
/**
 * Return a tuple containing a copy of the `NonEmptyReadonlyArray` without its last element, and that last element.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const unappend: <A>(self: readonly [A, ...A[]]) => [arrayWithoutLastElement: Array<A>, lastElement: A];
/**
 * Get the first element of a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const head: <A>(self: ReadonlyArray<A>) => Option<A>;
/**
 * @category getters
 * @since 2.0.0
 */
export declare const headNonEmpty: <A>(self: NonEmptyReadonlyArray<A>) => A;
/**
 * Get the last element in a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const last: <A>(self: ReadonlyArray<A>) => Option<A>;
/**
 * @category getters
 * @since 2.0.0
 */
export declare const lastNonEmpty: <A>(self: readonly [A, ...A[]]) => A;
/**
 * Get all but the first element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const tail: <A>(self: Iterable<A>) => Option<Array<A>>;
/**
 * @category getters
 * @since 2.0.0
 */
export declare const tailNonEmpty: <A>(self: readonly [A, ...A[]]) => Array<A>;
/**
 * Get all but the last element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const init: <A>(self: Iterable<A>) => Option<Array<A>>;
/**
 * Get all but the last element of a non empty array, creating a new array.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const initNonEmpty: <A>(self: readonly [A, ...A[]]) => Array<A>;
/**
 * Keep only a max number of elements from the start of an `Iterable`, creating a new `Array`.
 *
 * **Note**. `n` is normalized to a non negative integer.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const take: {
    (n: number): <A>(self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, n: number): Array<A>;
};
/**
 * Keep only a max number of elements from the end of an `Iterable`, creating a new `Array`.
 *
 * **Note**. `n` is normalized to a non negative integer.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const takeRight: {
    (n: number): <A>(self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, n: number): Array<A>;
};
/**
 * Calculate the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const takeWhile: {
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>;
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
};
/**
 * Split an `Iterable` into two parts:
 *
 * 1. the longest initial subarray for which all elements satisfy the specified predicate
 * 2. the remaining elements
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const span: {
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => [init: Array<B>, rest: Array<Exclude<A, B>>];
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [init: Array<A>, rest: Array<A>];
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): [init: Array<B>, rest: Array<Exclude<A, B>>];
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [init: Array<A>, rest: Array<A>];
};
/**
 * Drop a max number of elements from the start of an `Iterable`, creating a new `Array`.
 *
 * **Note**. `n` is normalized to a non negative integer.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const drop: {
    (n: number): <A>(self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, n: number): Array<A>;
};
/**
 * Drop a max number of elements from the end of an `Iterable`, creating a new `Array`.
 *
 * **Note**. `n` is normalized to a non negative integer.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const dropRight: {
    (n: number): <A>(self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, n: number): Array<A>;
};
/**
 * Remove the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`.
 *
 * @category getters
 * @since 2.0.0
 */
export declare const dropWhile: {
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
};
/**
 * Return the first index for which a predicate holds.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const findFirstIndex: {
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<number>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<number>;
};
/**
 * Return the last index for which a predicate holds.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const findLastIndex: {
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<number>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<number>;
};
/**
 * Returns the first element that satisfies the specified
 * predicate, or `None` if no such element exists.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const findFirst: {
    <A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>;
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>;
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>;
    <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>;
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>;
};
/**
 * Find the last element for which a predicate holds.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const findLast: {
    <A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>;
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>;
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>;
    <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>;
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>;
};
/**
 * Insert an element at the specified index, creating a new `NonEmptyArray`,
 * or return `None` if the index is out of bounds.
 *
 * @since 2.0.0
 */
export declare const insertAt: {
    <B>(i: number, b: B): <A>(self: Iterable<A>) => Option<NonEmptyArray<A | B>>;
    <A, B>(self: Iterable<A>, i: number, b: B): Option<NonEmptyArray<A | B>>;
};
/**
 * Change the element at the specified index, creating a new `Array`,
 * or return a copy of the input if the index is out of bounds.
 *
 * @since 2.0.0
 */
export declare const replace: {
    <B>(i: number, b: B): <A>(self: Iterable<A>) => Array<A | B>;
    <A, B>(self: Iterable<A>, i: number, b: B): Array<A | B>;
};
/**
 * @since 2.0.0
 */
export declare const replaceOption: {
    <B>(i: number, b: B): <A>(self: Iterable<A>) => Option<Array<A | B>>;
    <A, B>(self: Iterable<A>, i: number, b: B): Option<Array<A | B>>;
};
/**
 * Apply a function to the element at the specified index, creating a new `Array`,
 * or return a copy of the input if the index is out of bounds.
 *
 * @since 2.0.0
 */
export declare const modify: {
    <A, B>(i: number, f: (a: A) => B): (self: Iterable<A>) => Array<A | B>;
    <A, B>(self: Iterable<A>, i: number, f: (a: A) => B): Array<A | B>;
};
/**
 * Apply a function to the element at the specified index, creating a new `Array`,
 * or return `None` if the index is out of bounds.
 *
 * @since 2.0.0
 */
export declare const modifyOption: {
    <A, B>(i: number, f: (a: A) => B): (self: Iterable<A>) => Option<Array<A | B>>;
    <A, B>(self: Iterable<A>, i: number, f: (a: A) => B): Option<Array<A | B>>;
};
/**
 * Delete the element at the specified index, creating a new `Array`,
 * or return a copy of the input if the index is out of bounds.
 *
 * @since 2.0.0
 */
export declare const remove: {
    (i: number): <A>(self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, i: number): Array<A>;
};
/**
 * Reverse an `Iterable`, creating a new `Array`.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const reverse: <S extends readonly [any, ...any[]] | Iterable<any>>(self: S) => S extends readonly [infer A, ...(infer A)[]] ? [A, ...A[]] : S extends Iterable<infer A_1> ? A_1[] : never;
/**
 * Create a new array with elements sorted in increasing order based on the specified comparator.
 * If the input is a `NonEmptyReadonlyArray`, the output will also be a `NonEmptyReadonlyArray`.
 *
 * @category sorting
 * @since 2.0.0
 */
export declare const sort: {
    <B>(O: Order.Order<B>): <A extends B, S extends ReadonlyArray<A> | Iterable<A>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>;
    <A extends B, B>(self: NonEmptyReadonlyArray<A>, O: Order.Order<B>): NonEmptyArray<A>;
    <A extends B, B>(self: Iterable<A>, O: Order.Order<B>): Array<A>;
};
/**
 * @since 2.0.0
 * @category elements
 */
export declare const sortWith: {
    <S extends Iterable<any> | NonEmptyReadonlyArray<any>, B>(f: (a: ReadonlyArray.Infer<S>) => B, order: Order.Order<B>): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>;
    <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B, O: Order.Order<B>): NonEmptyArray<A>;
    <A, B>(self: Iterable<A>, f: (a: A) => B, order: Order.Order<B>): Array<A>;
};
/**
 * Sort the elements of an `Iterable` in increasing order, where elements are compared
 * using first `orders[0]`, then `orders[1]`, etc...
 *
 * @category sorting
 * @since 2.0.0
 */
export declare const sortBy: <S extends readonly [any, ...any[]] | Iterable<any>>(...orders: ReadonlyArray<Order.Order<ReadonlyArray.Infer<S>>>) => (self: S) => S extends readonly [infer A, ...(infer A)[]] ? [A, ...A[]] : S extends Iterable<infer A_1> ? A_1[] : never;
/**
 * Takes two `Iterable`s and returns an `Array` of corresponding pairs.
 * If one input `Iterable` is short, excess elements of the
 * longer `Iterable` are discarded.
 *
 * @category zipping
 * @since 2.0.0
 */
export declare const zip: {
    <B>(that: NonEmptyReadonlyArray<B>): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<[A, B]>;
    <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<[A, B]>;
    <A, B>(self: NonEmptyReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<[A, B]>;
    <A, B>(self: Iterable<A>, that: Iterable<B>): Array<[A, B]>;
};
/**
 * Apply a function to pairs of elements at the same index in two `Iterable`s, collecting the results in a new `Array`. If one
 * input `Iterable` is short, excess elements of the longer `Iterable` are discarded.
 *
 * @category zipping
 * @since 2.0.0
 */
export declare const zipWith: {
    <B, A, C>(that: NonEmptyReadonlyArray<B>, f: (a: A, b: B) => C): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<C>;
    <B, A, C>(that: Iterable<B>, f: (a: A, b: B) => C): (self: Iterable<A>) => Array<C>;
    <A, B, C>(self: NonEmptyReadonlyArray<A>, that: NonEmptyReadonlyArray<B>, f: (a: A, b: B) => C): NonEmptyArray<C>;
    <B, A, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Array<C>;
};
/**
 * This function is the inverse of `zip`. Takes an `Iterable` of pairs and return two corresponding `Array`s.
 *
 * @since 2.0.0
 */
export declare const unzip: <S extends Iterable<readonly [any, any]> | NonEmptyReadonlyArray<readonly [any, any]>>(self: S) => S extends NonEmptyReadonlyArray<readonly [infer A, infer B]> ? [NonEmptyArray<A>, NonEmptyArray<B>] : S extends Iterable<readonly [infer A, infer B]> ? [Array<A>, Array<B>] : never;
/**
 * Places an element in between members of an `Iterable`.
 * If the input is a non-empty array, the result is also a non-empty array.
 *
 * @since 2.0.0
 */
export declare const intersperse: {
    <B>(middle: B): <S extends ReadonlyArray<any> | Iterable<any>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, middle: B): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, middle: B): Array<A | B>;
};
/**
 * Apply a function to the head, creating a new `NonEmptyReadonlyArray`.
 *
 * @since 2.0.0
 */
export declare const modifyNonEmptyHead: {
    <A, B>(f: (a: A) => B): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B): NonEmptyArray<A | B>;
};
/**
 * Change the head, creating a new `NonEmptyReadonlyArray`.
 *
 * @since 2.0.0
 */
export declare const setNonEmptyHead: {
    <B>(b: B): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B>;
};
/**
 * Apply a function to the last element, creating a new `NonEmptyReadonlyArray`.
 *
 * @since 2.0.0
 */
export declare const modifyNonEmptyLast: {
    <A, B>(f: (a: A) => B): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B): NonEmptyArray<A | B>;
};
/**
 * Change the last element, creating a new `NonEmptyReadonlyArray`.
 *
 * @since 2.0.0
 */
export declare const setNonEmptyLast: {
    <B>(b: B): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>;
    <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B>;
};
/**
 * Rotate an `Iterable` by `n` steps.
 * If the input is a non-empty array, the result is also a non-empty array.
 *
 * @since 2.0.0
 */
export declare const rotate: {
    (n: number): <S extends ReadonlyArray<any> | Iterable<any>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>;
    <A>(self: NonEmptyReadonlyArray<A>, n: number): NonEmptyArray<A>;
    <A>(self: Iterable<A>, n: number): Array<A>;
};
/**
 * Returns a function that checks if a `ReadonlyArray` contains a given value using a provided `isEquivalent` function.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const containsWith: <A>(isEquivalent: (self: A, that: A) => boolean) => {
    (a: A): (self: Iterable<A>) => boolean;
    (self: Iterable<A>, a: A): boolean;
};
/**
 * Returns a function that checks if a `ReadonlyArray` contains a given value using the default `Equivalence`.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const contains: {
    <A>(a: A): (self: Iterable<A>) => boolean;
    <A>(self: Iterable<A>, a: A): boolean;
};
/**
 * A useful recursion pattern for processing an `Iterable` to produce a new `Array`, often used for "chopping" up the input
 * `Iterable`. Typically chop is called with some function that will consume an initial prefix of the `Iterable` and produce a
 * value and the rest of the `Array`.
 *
 * @since 2.0.0
 */
export declare const chop: {
    <S extends ReadonlyArray<any> | Iterable<any>, B>(f: (as: NonEmptyReadonlyArray<ReadonlyArray.Infer<S>>) => readonly [B, ReadonlyArray<ReadonlyArray.Infer<S>>]): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>;
    <A, B>(self: NonEmptyReadonlyArray<A>, f: (as: NonEmptyReadonlyArray<A>) => readonly [B, ReadonlyArray<A>]): NonEmptyArray<B>;
    <A, B>(self: Iterable<A>, f: (as: NonEmptyReadonlyArray<A>) => readonly [B, ReadonlyArray<A>]): Array<B>;
};
/**
 * Splits an `Iterable` into two segments, with the first segment containing a maximum of `n` elements.
 * The value of `n` can be `0`.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const splitAt: {
    (n: number): <A>(self: Iterable<A>) => [beforeIndex: Array<A>, fromIndex: Array<A>];
    <A>(self: Iterable<A>, n: number): [beforeIndex: Array<A>, fromIndex: Array<A>];
};
/**
 * Splits a `NonEmptyReadonlyArray` into two segments, with the first segment containing a maximum of `n` elements.
 * The value of `n` must be `>= 1`.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const splitNonEmptyAt: {
    (n: number): <A>(self: NonEmptyReadonlyArray<A>) => [beforeIndex: NonEmptyArray<A>, fromIndex: Array<A>];
    <A>(self: NonEmptyReadonlyArray<A>, n: number): [beforeIndex: NonEmptyArray<A>, fromIndex: Array<A>];
};
/**
 * Splits this iterable into `n` equally sized arrays.
 *
 * @since 2.0.0
 * @category splitting
 */
export declare const split: {
    (n: number): <A>(self: Iterable<A>) => Array<Array<A>>;
    <A>(self: Iterable<A>, n: number): Array<Array<A>>;
};
/**
 * Splits this iterable on the first element that matches this predicate.
 * Returns a tuple containing two arrays: the first one is before the match, and the second one is from the match onward.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const splitWhere: {
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [beforeMatch: Array<A>, fromMatch: Array<A>];
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [beforeMatch: Array<A>, fromMatch: Array<A>];
};
/**
 * @since 2.0.0
 */
export declare const copy: {
    <A>(self: NonEmptyReadonlyArray<A>): NonEmptyArray<A>;
    <A>(self: ReadonlyArray<A>): Array<A>;
};
/**
 * Splits an `Iterable` into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of
 * the `Iterable`. Note that `chunksOf(n)([])` is `[]`, not `[[]]`. This is intentional, and is consistent with a recursive
 * definition of `chunksOf`; it satisfies the property that
 *
 * ```ts
 * chunksOf(n)(xs).concat(chunksOf(n)(ys)) == chunksOf(n)(xs.concat(ys)))
 * ```
 *
 * whenever `n` evenly divides the length of `self`.
 *
 * @category splitting
 * @since 2.0.0
 */
export declare const chunksOf: {
    (n: number): <S extends ReadonlyArray<any> | Iterable<any>>(self: S) => ReadonlyArray.With<S, NonEmptyArray<ReadonlyArray.Infer<S>>>;
    <A>(self: NonEmptyReadonlyArray<A>, n: number): NonEmptyArray<NonEmptyArray<A>>;
    <A>(self: Iterable<A>, n: number): Array<NonEmptyArray<A>>;
};
/**
 * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s using the provided `isEquivalent` function.
 *
 * @category grouping
 * @since 2.0.0
 */
export declare const groupWith: {
    <A>(isEquivalent: (self: A, that: A) => boolean): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmptyArray<A>>;
    <A>(self: NonEmptyReadonlyArray<A>, isEquivalent: (self: A, that: A) => boolean): NonEmptyArray<NonEmptyArray<A>>;
};
/**
 * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s.
 *
 * @category grouping
 * @since 2.0.0
 */
export declare const group: <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmptyArray<A>>;
/**
 * Splits an `Iterable` into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning
 * function on each element, and grouping the results according to values returned
 *
 * @category grouping
 * @since 2.0.0
 */
export declare const groupBy: {
    <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>;
    <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>;
};
/**
 * @since 2.0.0
 */
export declare const unionWith: {
    <S extends ReadonlyArray<any> | Iterable<any>, T extends ReadonlyArray<any> | Iterable<any>>(that: T, isEquivalent: (self: ReadonlyArray.Infer<S>, that: ReadonlyArray.Infer<T>) => boolean): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>;
    <A, B>(self: NonEmptyReadonlyArray<A>, that: Iterable<B>, isEquivalent: (self: A, that: B) => boolean): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, that: NonEmptyReadonlyArray<B>, isEquivalent: (self: A, that: B) => boolean): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, that: Iterable<B>, isEquivalent: (self: A, that: B) => boolean): Array<A | B>;
};
/**
 * @since 2.0.0
 */
export declare const union: {
    <T extends ReadonlyArray<any> | Iterable<any>>(that: T): <S extends ReadonlyArray<any> | Iterable<any>>(self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>;
    <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>;
    <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>;
    <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
};
/**
 * Creates an `Array` of unique values that are included in all given `Iterable`s using the provided `isEquivalent` function.
 * The order and references of result values are determined by the first `Iterable`.
 *
 * @since 2.0.0
 */
export declare const intersectionWith: <A>(isEquivalent: (self: A, that: A) => boolean) => {
    (that: Iterable<A>): (self: Iterable<A>) => Array<A>;
    (self: Iterable<A>, that: Iterable<A>): Array<A>;
};
/**
 * Creates an `Array` of unique values that are included in all given `Iterable`s.
 * The order and references of result values are determined by the first `Iterable`.
 *
 * @since 2.0.0
 */
export declare const intersection: {
    <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<A & B>;
    <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A & B>;
};
/**
 * Creates a `Array` of values not included in the other given `Iterable` using the provided `isEquivalent` function.
 * The order and references of result values are determined by the first `Iterable`.
 *
 * @since 2.0.0
 */
export declare const differenceWith: <A>(isEquivalent: (self: A, that: A) => boolean) => {
    (that: Iterable<A>): (self: Iterable<A>) => Array<A>;
    (self: Iterable<A>, that: Iterable<A>): Array<A>;
};
/**
 * Creates a `Array` of values not included in the other given `Iterable`.
 * The order and references of result values are determined by the first `Iterable`.
 *
 * @since 2.0.0
 */
export declare const difference: {
    <A>(that: Iterable<A>): (self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, that: Iterable<A>): Array<A>;
};
/**
 * @category constructors
 * @since 2.0.0
 */
export declare const empty: <A = never>() => Array<A>;
/**
 * Constructs a new `NonEmptyArray<A>` from the specified value.
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const of: <A>(a: A) => [A, ...A[]];
/**
 * @since 2.0.0
 */
export declare namespace ReadonlyArray {
    /**
     * @since 2.0.0
     */
    type Infer<S extends ReadonlyArray<any> | Iterable<any>> = S extends ReadonlyArray<infer A> ? A : S extends Iterable<infer A> ? A : never;
    /**
     * @since 2.0.0
     */
    type With<S extends ReadonlyArray<any> | Iterable<any>, A> = S extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A> : Array<A>;
    /**
     * @since 2.0.0
     */
    type OrNonEmpty<S extends ReadonlyArray<any> | Iterable<any>, T extends ReadonlyArray<any> | Iterable<any>, A> = S extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A> : T extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A> : Array<A>;
    /**
     * @since 2.0.0
     */
    type AndNonEmpty<S extends ReadonlyArray<any> | Iterable<any>, T extends ReadonlyArray<any> | Iterable<any>, A> = S extends NonEmptyReadonlyArray<any> ? T extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A> : Array<A> : Array<A>;
    /**
     * @since 2.0.0
     */
    type Flatten<T extends ReadonlyArray<ReadonlyArray<any>>> = T extends NonEmptyReadonlyArray<NonEmptyReadonlyArray<infer A>> ? NonEmptyArray<A> : T extends ReadonlyArray<ReadonlyArray<infer A>> ? Array<A> : never;
}
/**
 * @category mapping
 * @since 2.0.0
 */
export declare const map: {
    <S extends ReadonlyArray<any>, B>(f: (a: ReadonlyArray.Infer<S>, i: number) => B): (self: S) => ReadonlyArray.With<S, B>;
    <S extends ReadonlyArray<any>, B>(self: S, f: (a: ReadonlyArray.Infer<S>, i: number) => B): ReadonlyArray.With<S, B>;
};
/**
 * Applies a function to each element in an array and returns a new array containing the concatenated mapped elements.
 *
 * @category sequencing
 * @since 2.0.0
 */
export declare const flatMap: {
    <S extends ReadonlyArray<any>, T extends ReadonlyArray<any>>(f: (a: ReadonlyArray.Infer<S>, i: number) => T): (self: S) => ReadonlyArray.AndNonEmpty<S, T, ReadonlyArray.Infer<T>>;
    <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A, i: number) => NonEmptyReadonlyArray<B>): NonEmptyArray<B>;
    <A, B>(self: ReadonlyArray<A>, f: (a: A, i: number) => ReadonlyArray<B>): Array<B>;
};
/**
 * Flattens an array of arrays into a single array by concatenating all arrays.
 *
 * @category sequencing
 * @since 2.0.0
 */
export declare const flatten: <S extends ReadonlyArray<ReadonlyArray<any>>>(self: S) => ReadonlyArray.Flatten<S>;
/**
 * @category filtering
 * @since 2.0.0
 */
export declare const filterMap: {
    <A, B>(f: (a: A, i: number) => Option<B>): (self: Iterable<A>) => Array<B>;
    <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Array<B>;
};
/**
 * Transforms all elements of the `readonlyArray` for as long as the specified function returns some value
 *
 * @category filtering
 * @since 2.0.0
 */
export declare const filterMapWhile: {
    <A, B>(f: (a: A, i: number) => Option<B>): (self: Iterable<A>) => Array<B>;
    <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Array<B>;
};
/**
 * @category filtering
 * @since 2.0.0
 */
export declare const partitionMap: {
    <A, B, C>(f: (a: A, i: number) => Either<C, B>): (self: Iterable<A>) => [left: Array<B>, right: Array<C>];
    <A, B, C>(self: Iterable<A>, f: (a: A, i: number) => Either<C, B>): [left: Array<B>, right: Array<C>];
};
/**
 * Retrieves the `Some` values from an `Iterable` of `Option`s, collecting them into an array.
 *
 * @example
 * import { Array, Option } from "effect"
 *
 * assert.deepStrictEqual(
 *   Array.getSomes([Option.some(1), Option.none(), Option.some(2)]),
 *   [1, 2]
 * )
 *
 * @category filtering
 * @since 2.0.0
 */
export declare const getSomes: <A>(self: Iterable<Option<A>>) => Array<A>;
/**
 * Retrieves the `Left` values from an `Iterable` of `Either`s, collecting them into an array.
 *
 * @example
 * import { Array, Either } from "effect"
 *
 * assert.deepStrictEqual(
 *   Array.getLefts([Either.right(1), Either.left("err"), Either.right(2)]),
 *   ["err"]
 * )
 *
 * @category filtering
 * @since 2.0.0
 */
export declare const getLefts: <R, L>(self: Iterable<Either<R, L>>) => Array<L>;
/**
 * Retrieves the `Right` values from an `Iterable` of `Either`s, collecting them into an array.
 *
 * @example
 * import { Array, Either } from "effect"
 *
 * assert.deepStrictEqual(
 *   Array.getRights([Either.right(1), Either.left("err"), Either.right(2)]),
 *   [1, 2]
 * )
 *
 * @category filtering
 * @since 2.0.0
 */
export declare const getRights: <R, L>(self: Iterable<Either<R, L>>) => Array<R>;
/**
 * @category filtering
 * @since 2.0.0
 */
export declare const filter: {
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>;
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>;
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
};
/**
 * Separate elements based on a predicate that also exposes the index of the element.
 *
 * @category filtering
 * @since 2.0.0
 */
export declare const partition: {
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => [excluded: Array<Exclude<A, B>>, satisfying: Array<B>];
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [excluded: Array<A>, satisfying: Array<A>];
    <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): [excluded: Array<Exclude<A, B>>, satisfying: Array<B>];
    <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [excluded: Array<A>, satisfying: Array<A>];
};
/**
 * @category filtering
 * @since 2.0.0
 */
export declare const separate: <R, L>(self: Iterable<Either<R, L>>) => [Array<L>, Array<R>];
/**
 * @category folding
 * @since 2.0.0
 */
export declare const reduce: {
    <B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B;
    <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B;
};
/**
 * @category folding
 * @since 2.0.0
 */
export declare const reduceRight: {
    <B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B;
    <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B;
};
/**
 * @category lifting
 * @since 2.0.0
 */
export declare const liftPredicate: {
    <A, B extends A>(refinement: Refinement<A, B>): (a: A) => Array<B>;
    <A>(predicate: Predicate<A>): <B extends A>(b: B) => Array<B>;
};
/**
 * @category lifting
 * @since 2.0.0
 */
export declare const liftOption: <A extends unknown[], B>(f: (...a: A) => Option<B>) => (...a: A) => Array<B>;
/**
 * @category conversions
 * @since 2.0.0
 */
export declare const fromNullable: <A>(a: A) => Array<NonNullable<A>>;
/**
 * @category lifting
 * @since 2.0.0
 */
export declare const liftNullable: <A extends unknown[], B>(f: (...a: A) => B | null | undefined) => (...a: A) => Array<NonNullable<B>>;
/**
 * @category sequencing
 * @since 2.0.0
 */
export declare const flatMapNullable: {
    <A, B>(f: (a: A) => B | null | undefined): (self: ReadonlyArray<A>) => Array<NonNullable<B>>;
    <A, B>(self: ReadonlyArray<A>, f: (a: A) => B | null | undefined): Array<NonNullable<B>>;
};
/**
 * @category lifting
 * @since 2.0.0
 */
export declare const liftEither: <A extends unknown[], E, B>(f: (...a: A) => Either<B, E>) => (...a: A) => Array<B>;
/**
 * Check if a predicate holds true for every `ReadonlyArray` element.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const every: {
    <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: ReadonlyArray<A>) => self is ReadonlyArray<B>;
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: ReadonlyArray<A>) => boolean;
    <A, B extends A>(self: ReadonlyArray<A>, refinement: (a: A, i: number) => a is B): self is ReadonlyArray<B>;
    <A>(self: ReadonlyArray<A>, predicate: (a: A, i: number) => boolean): boolean;
};
/**
 * Check if a predicate holds true for some `ReadonlyArray` element.
 *
 * @category elements
 * @since 2.0.0
 */
export declare const some: {
    <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: ReadonlyArray<A>) => self is NonEmptyReadonlyArray<A>;
    <A>(self: ReadonlyArray<A>, predicate: (a: A, i: number) => boolean): self is NonEmptyReadonlyArray<A>;
};
/**
 * @since 2.0.0
 */
export declare const extend: {
    <A, B>(f: (as: ReadonlyArray<A>) => B): (self: ReadonlyArray<A>) => Array<B>;
    <A, B>(self: ReadonlyArray<A>, f: (as: ReadonlyArray<A>) => B): Array<B>;
};
/**
 * @since 2.0.0
 */
export declare const min: {
    <A>(O: Order.Order<A>): (self: NonEmptyReadonlyArray<A>) => A;
    <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A;
};
/**
 * @since 2.0.0
 */
export declare const max: {
    <A>(O: Order.Order<A>): (self: NonEmptyReadonlyArray<A>) => A;
    <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A;
};
/**
 * @category constructors
 * @since 2.0.0
 */
export declare const unfold: <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>) => Array<A>;
/**
 * This function creates and returns a new `Order` for an array of values based on a given `Order` for the elements of the array.
 * The returned `Order` compares two arrays by applying the given `Order` to each element in the arrays.
 * If all elements are equal, the arrays are then compared based on their length.
 * It is useful when you need to compare two arrays of the same type and you have a specific way of comparing each element of the array.
 *
 * @category instances
 * @since 2.0.0
 */
export declare const getOrder: <A>(O: Order.Order<A>) => Order.Order<ReadonlyArray<A>>;
/**
 * @category instances
 * @since 2.0.0
 */
export declare const getEquivalence: <A>(isEquivalent: Equivalence.Equivalence<A>) => Equivalence.Equivalence<ReadonlyArray<A>>;
/**
 * Iterate over the `Iterable` applying `f`.
 *
 * @since 2.0.0
 */
export declare const forEach: {
    <A>(f: (a: A, i: number) => void): (self: Iterable<A>) => void;
    <A>(self: Iterable<A>, f: (a: A, i: number) => void): void;
};
/**
 * Remove duplicates from an `Iterable` using the provided `isEquivalent` function,
 * preserving the order of the first occurrence of each element.
 *
 * @since 2.0.0
 */
export declare const dedupeWith: {
    <S extends ReadonlyArray<any> | Iterable<any>>(isEquivalent: (self: ReadonlyArray.Infer<S>, that: ReadonlyArray.Infer<S>) => boolean): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>;
    <A>(self: NonEmptyReadonlyArray<A>, isEquivalent: (self: A, that: A) => boolean): NonEmptyArray<A>;
    <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>;
};
/**
 * Remove duplicates from an `Iterable`, preserving the order of the first occurrence of each element.
 * The equivalence used to compare elements is provided by `Equal.equivalence()` from the `Equal` module.
 *
 * @since 2.0.0
 */
export declare const dedupe: <S extends readonly [any, ...any[]] | Iterable<any>>(self: S) => S extends readonly [infer A, ...(infer A)[]] ? [A, ...A[]] : S extends Iterable<infer A_1> ? A_1[] : never;
/**
 * Deduplicates adjacent elements that are identical using the provided `isEquivalent` function.
 *
 * @since 2.0.0
 */
export declare const dedupeAdjacentWith: {
    <A>(isEquivalent: (self: A, that: A) => boolean): (self: Iterable<A>) => Array<A>;
    <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>;
};
/**
 * Deduplicates adjacent elements that are identical.
 *
 * @since 2.0.0
 */
export declare const dedupeAdjacent: <A>(self: Iterable<A>) => Array<A>;
/**
 * Joins the elements together with "sep" in the middle.
 *
 * @since 2.0.0
 * @category folding
 */
export declare const join: {
    (sep: string): (self: Iterable<string>) => string;
    (self: Iterable<string>, sep: string): string;
};
/**
 * Statefully maps over the chunk, producing new elements of type `B`.
 *
 * @since 2.0.0
 * @category folding
 */
export declare const mapAccum: {
    <S, A, B>(s: S, f: (s: S, a: A, i: number) => readonly [S, B]): (self: Iterable<A>) => [state: S, mappedArray: Array<B>];
    <S, A, B>(self: Iterable<A>, s: S, f: (s: S, a: A, i: number) => readonly [S, B]): [state: S, mappedArray: Array<B>];
};
/**
 * Zips this chunk crosswise with the specified chunk using the specified combiner.
 *
 * @since 2.0.0
 * @category elements
 */
export declare const cartesianWith: {
    <A, B, C>(that: ReadonlyArray<B>, f: (a: A, b: B) => C): (self: ReadonlyArray<A>) => Array<C>;
    <A, B, C>(self: ReadonlyArray<A>, that: ReadonlyArray<B>, f: (a: A, b: B) => C): Array<C>;
};
/**
 * Zips this chunk crosswise with the specified chunk.
 *
 * @since 2.0.0
 * @category elements
 */
export declare const cartesian: {
    <B>(that: ReadonlyArray<B>): <A>(self: ReadonlyArray<A>) => Array<[A, B]>;
    <A, B>(self: ReadonlyArray<A>, that: ReadonlyArray<B>): Array<[A, B]>;
};
/**
 * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
 *
 * It can be used to simulate "array comprehension".
 * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
 *
 * Here's how the do simulation works:
 *
 * 1. Start the do simulation using the `Do` value
 * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
 * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
 * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
 * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
 *
 * @see {@link bindTo}
 * @see {@link bind}
 * @see {@link let_ let}
 *
 * @example
 * import { Array as Arr, pipe } from "effect"
 * const doResult = pipe(
 *   Arr.Do,
 *   Arr.bind("x", () => [1, 3, 5]),
 *   Arr.bind("y", () => [2, 4, 6]),
 *   Arr.filter(({ x, y }) => x < y), // condition
 *   Arr.map(({ x, y }) => [x, y] as const) // transformation
 * )
 * assert.deepStrictEqual(doResult, [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]])
 *
 * // equivalent
 * const x = [1, 3, 5],
 *       y = [2, 4, 6],
 *       result = [];
 * for(let i = 0; i < x.length; i++) {
 *   for(let j = 0; j < y.length; j++) {
 *     const _x = x[i], _y = y[j];
 *     if(_x < _y) result.push([_x, _y] as const)
 *   }
 * }
 *
 * @category do notation
 * @since 3.2.0
 */
export declare const Do: ReadonlyArray<{}>;
/**
 * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
 *
 * It can be used to simulate "array comprehension".
 * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
 *
 * Here's how the do simulation works:
 *
 * 1. Start the do simulation using the `Do` value
 * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
 * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
 * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
 * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
 *
 * @see {@link bindTo}
 * @see {@link Do}
 * @see {@link let_ let}
 *
 * @example
 * import { Array as Arr, pipe } from "effect"
 * const doResult = pipe(
 *   Arr.Do,
 *   Arr.bind("x", () => [1, 3, 5]),
 *   Arr.bind("y", () => [2, 4, 6]),
 *   Arr.filter(({ x, y }) => x < y), // condition
 *   Arr.map(({ x, y }) => [x, y] as const) // transformation
 * )
 * assert.deepStrictEqual(doResult, [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]])
 *
 * // equivalent
 * const x = [1, 3, 5],
 *       y = [2, 4, 6],
 *       result = [];
 * for(let i = 0; i < x.length; i++) {
 *   for(let j = 0; j < y.length; j++) {
 *     const _x = x[i], _y = y[j];
 *     if(_x < _y) result.push([_x, _y] as const)
 *   }
 * }
 *
 * @category do notation
 * @since 3.2.0
 */
export declare const bind: {
    <A extends object, N extends string, B>(tag: Exclude<N, keyof A>, f: (a: A) => ReadonlyArray<B>): (self: ReadonlyArray<A>) => Array<{
        [K in N | keyof A]: K extends keyof A ? A[K] : B;
    }>;
    <A extends object, N extends string, B>(self: ReadonlyArray<A>, tag: Exclude<N, keyof A>, f: (a: A) => ReadonlyArray<B>): Array<{
        [K in N | keyof A]: K extends keyof A ? A[K] : B;
    }>;
};
/**
 * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
 *
 * It can be used to simulate "array comprehension".
 * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
 *
 * Here's how the do simulation works:
 *
 * 1. Start the do simulation using the `Do` value
 * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
 * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
 * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
 * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
 *
 * @see {@link bindTo}
 * @see {@link Do}
 * @see {@link let_ let}
 *
 * @example
 * import { Array as Arr, pipe } from "effect"
 * const doResult = pipe(
 *   Arr.Do,
 *   Arr.bind("x", () => [1, 3, 5]),
 *   Arr.bind("y", () => [2, 4, 6]),
 *   Arr.filter(({ x, y }) => x < y), // condition
 *   Arr.map(({ x, y }) => [x, y] as const) // transformation
 * )
 * assert.deepStrictEqual(doResult, [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]])
 *
 * // equivalent
 * const x = [1, 3, 5],
 *       y = [2, 4, 6],
 *       result = [];
 * for(let i = 0; i < x.length; i++) {
 *   for(let j = 0; j < y.length; j++) {
 *     const _x = x[i], _y = y[j];
 *     if(_x < _y) result.push([_x, _y] as const)
 *   }
 * }
 *
 * @category do notation
 * @since 3.2.0
 */
export declare const bindTo: {
    <N extends string>(tag: N): <A>(self: ReadonlyArray<A>) => Array<{
        [K in N]: A;
    }>;
    <A, N extends string>(self: ReadonlyArray<A>, tag: N): Array<{
        [K in N]: A;
    }>;
};
declare const let_: {
    <N extends string, B, A extends object>(tag: Exclude<N, keyof A>, f: (a: A) => B): (self: ReadonlyArray<A>) => Array<{
        [K in N | keyof A]: K extends keyof A ? A[K] : B;
    }>;
    <N extends string, A extends object, B>(self: ReadonlyArray<A>, tag: Exclude<N, keyof A>, f: (a: A) => B): Array<{
        [K in N | keyof A]: K extends keyof A ? A[K] : B;
    }>;
};
export { 
/**
 * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
 *
 * It can be used to simulate "array comprehension".
 * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
 *
 * Here's how the do simulation works:
 *
 * 1. Start the do simulation using the `Do` value
 * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
 * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
 * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
 * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
 *
 * @see {@link bindTo}
 * @see {@link bind}
 * @see {@link Do}
 *
 * @example
 * import { Array as Arr, pipe } from "effect"
 * const doResult = pipe(
 *   Arr.Do,
 *   Arr.bind("x", () => [1, 3, 5]),
 *   Arr.bind("y", () => [2, 4, 6]),
 *   Arr.filter(({ x, y }) => x < y), // condition
 *   Arr.map(({ x, y }) => [x, y] as const) // transformation
 * )
 * assert.deepStrictEqual(doResult, [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]])
 *
 * // equivalent
 * const x = [1, 3, 5],
 *       y = [2, 4, 6],
 *       result = [];
 * for(let i = 0; i < x.length; i++) {
 *   for(let j = 0; j < y.length; j++) {
 *     const _x = x[i], _y = y[j];
 *     if(_x < _y) result.push([_x, _y] as const)
 *   }
 * }
 *
 * @category do notation
 * @since 3.2.0
 */
let_ as let };
//# sourceMappingURL=Array.d.ts.map