<T extends Iterable<any>>(that: T): <S extends 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>Computes the union of two arrays, removing duplicates using
Equal.equivalence().
Example (Computing array unions)
import { Array } from "effect"
console.log(Array.union([1, 2], [2, 3])) // [1, 2, 3]export const const union: {
<T extends Iterable<any>>(that: T): <
S extends 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>
}
Computes the union of two arrays, removing duplicates using
Equal.equivalence().
Example (Computing array unions)
import { Array } from "effect"
console.log(Array.union([1, 2], [2, 3])) // [1, 2, 3]
union: {
<function (type parameter) T in <T extends Iterable<any>>(that: T): <S extends Iterable<any>>(self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>T extends interface Iterable<T, TReturn = any, TNext = any>Iterable<any>>(
that: T extends Iterable<any>that: function (type parameter) T in <T extends Iterable<any>>(that: T): <S extends Iterable<any>>(self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>T
): <function (type parameter) S in <S extends Iterable<any>>(self: S): ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>S extends interface Iterable<T, TReturn = any, TNext = any>Iterable<any>>(
self: S extends Iterable<any>self: function (type parameter) S in <S extends Iterable<any>>(self: S): ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>S
) => ReadonlyArray.type ReadonlyArray.OrNonEmpty<S extends Iterable<any>, T extends Iterable<any>, A> = S extends readonly [any, ...any[]] ? [A, ...A[]] : T extends readonly [any, ...any[]] ? [A, ...A[]] : A[]Creates a non-empty array if either input is non-empty.
Example (Preserving non-emptiness from either input)
import type { Array } from "effect"
type Result = Array.ReadonlyArray.OrNonEmpty<
readonly [number],
ReadonlyArray<string>,
number
>
// Result is NonEmptyArray<number>
OrNonEmpty<function (type parameter) S in <S extends Iterable<any>>(self: S): ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>S, function (type parameter) T in <T extends Iterable<any>>(that: T): <S extends Iterable<any>>(self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>T, ReadonlyArray.type ReadonlyArray.Infer<S extends Iterable<any>> = S extends readonly (infer A)[] ? A : S extends Iterable<infer A> ? A : neverInfers the element type of an iterable.
Example (Inferring an element type)
import type { Array } from "effect"
type StringArrayType = Array.ReadonlyArray.Infer<ReadonlyArray<string>>
// StringArrayType is string
Infer<function (type parameter) S in <S extends Iterable<any>>(self: S): ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>S> | ReadonlyArray.type ReadonlyArray.Infer<S extends Iterable<any>> = S extends readonly (infer A)[] ? A : S extends Iterable<infer A> ? A : neverInfers the element type of an iterable.
Example (Inferring an element type)
import type { Array } from "effect"
type StringArrayType = Array.ReadonlyArray.Infer<ReadonlyArray<string>>
// StringArrayType is string
Infer<function (type parameter) T in <T extends Iterable<any>>(that: T): <S extends Iterable<any>>(self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>T>>
<function (type parameter) A in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>A, function (type parameter) B in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>B>(self: NonEmptyReadonlyArray<A>(parameter) self: {
0: A;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A>>): Array<A>; (...items: Array<A | ConcatArray<A>>): Array<A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A>;
indexOf: (searchElement: A, fromIndex?: number) => number;
lastIndexOf: (searchElement: A, fromIndex?: number) => number;
every: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): Array<A> };
reduce: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
reduceRight: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
find: { (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findIndex: (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A>;
includes: (searchElement: A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A, index: number, array: Array<A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A | undefined;
findLast: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findLastIndex: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A>;
toSorted: (compareFn?: ((a: A, b: A) => number) | undefined) => Array<A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A>): Array<A>; (start: number, deleteCount?: number): Array<A> };
with: (index: number, value: A) => Array<A>;
}
self: type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) A in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>A>, that: readonly B[]that: interface ReadonlyArray<T>ReadonlyArray<function (type parameter) B in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>B>): type NonEmptyArray<A> = [A, ...A[]]A mutable array guaranteed to have at least one element.
When to use
Use when mutation is acceptable and non-emptiness must be tracked at the type
level.
Details
This is the mutable counterpart of
NonEmptyReadonlyArray
. Most Array
module functions return NonEmptyArray when the result is guaranteed
non-empty.
Example (Typing a mutable non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyArray<number> = [1, 2, 3]
nonEmpty.push(4)
NonEmptyArray<function (type parameter) A in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>A | function (type parameter) B in <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>B>
<function (type parameter) A in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>A, function (type parameter) B in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>B>(self: readonly A[]self: interface ReadonlyArray<T>ReadonlyArray<function (type parameter) A in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>A>, that: NonEmptyReadonlyArray<B>(parameter) that: {
0: B;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<B>>): Array<B>; (...items: Array<B | ConcatArray<B>>): Array<B> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<B>;
indexOf: (searchElement: B, fromIndex?: number) => number;
lastIndexOf: (searchElement: B, fromIndex?: number) => number;
every: { (predicate: (value: B, index: number, array: ReadonlyArray<B>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: B, index: number, array: ReadonlyArray<B>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: B, index: number, array: ReadonlyArray<B>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: B, index: number, array: ReadonlyArray<B>) => void, thisArg?: any) => void;
map: (callbackfn: (value: B, index: number, array: ReadonlyArray<B>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: B, index: number, array: ReadonlyArray<B>) => value is S, thisArg?: any): Array<S>; (predicate: (value: B, index: number, array: ReadonlyArray<B>) => unknown, thisArg?: any): Array<B> };
reduce: { (callbackfn: (previousValue: B, currentValue: B, currentIndex: number, array: ReadonlyArray<B>) => B): B; (callbackfn: (previousValue: B, currentValue: B, currentIndex: number, array: ReadonlyArray<B>) => B, initialValue: B): B; (callbac…;
reduceRight: { (callbackfn: (previousValue: B, currentValue: B, currentIndex: number, array: ReadonlyArray<B>) => B): B; (callbackfn: (previousValue: B, currentValue: B, currentIndex: number, array: ReadonlyArray<B>) => B, initialValue: B): B; (callbac…;
find: { (predicate: (value: B, index: number, obj: ReadonlyArray<B>) => value is S, thisArg?: any): S | undefined; (predicate: (value: B, index: number, obj: ReadonlyArray<B>) => unknown, thisArg?: any): B | undefined };
findIndex: (predicate: (value: B, index: number, obj: ReadonlyArray<B>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, B]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<B>;
includes: (searchElement: B, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: B, index: number, array: Array<B>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => B | undefined;
findLast: { (predicate: (value: B, index: number, array: ReadonlyArray<B>) => value is S, thisArg?: any): S | undefined; (predicate: (value: B, index: number, array: ReadonlyArray<B>) => unknown, thisArg?: any): B | undefined };
findLastIndex: (predicate: (value: B, index: number, array: ReadonlyArray<B>) => unknown, thisArg?: any) => number;
toReversed: () => Array<B>;
toSorted: (compareFn?: ((a: B, b: B) => number) | undefined) => Array<B>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<B>): Array<B>; (start: number, deleteCount?: number): Array<B> };
with: (index: number, value: B) => Array<B>;
}
that: type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) B in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>B>): type NonEmptyArray<A> = [A, ...A[]]A mutable array guaranteed to have at least one element.
When to use
Use when mutation is acceptable and non-emptiness must be tracked at the type
level.
Details
This is the mutable counterpart of
NonEmptyReadonlyArray
. Most Array
module functions return NonEmptyArray when the result is guaranteed
non-empty.
Example (Typing a mutable non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyArray<number> = [1, 2, 3]
nonEmpty.push(4)
NonEmptyArray<function (type parameter) A in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>A | function (type parameter) B in <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>B>
<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A, function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A>, that: Iterable<B>that: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>): interface Array<T>Array<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A | function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>
} = dual<(...args: Array<any>) => any, <A, B>(self: Iterable<A>, that: Iterable<B>) => Array<A | B>>(arity: 2, body: <A, B>(self: Iterable<A>, that: Iterable<B>) => Array<A | B>): ((...args: Array<any>) => any) & (<A, B>(self: Iterable<A>, that: Iterable<B>) => Array<A | B>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A, function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A>, that: Iterable<B>that: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>): interface Array<T>Array<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A | function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B> => const unionWith: {
<
S extends Iterable<any>,
T extends 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>
}
unionWith(self: Iterable<A>self, that: Iterable<B>that, import EqualEqual.const asEquivalence: <
A
>() => Equivalence<A>
Wraps
equals
as an Equivalence<A>.
When to use
Use when you want to pass Equal.equals to APIs that require an
Equivalence.
Details
- Returns a function
(a: A, b: A) => boolean that delegates to
equals
.
- Pure; allocates a thin wrapper on each call.
Example (Deduplicating with Equal semantics)
import { Array, Equal } from "effect"
const eq = Equal.asEquivalence<number>()
const result = Array.dedupeWith([1, 2, 2, 3, 1], eq)
console.log(result) // [1, 2, 3]
asEquivalence<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>A | function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>B>())
)