Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Chunk

Stores many values in an immutable ordered collection.

A Chunk<A> is useful when you need to build or transform collections without changing the original collection. It is designed for efficient append, prepend, and concatenation. This module includes helpers for creating, reading, slicing, mapping, filtering, sorting, zipping, combining, and converting chunks to and from arrays and iterables.

81 exports Since v2.0.0 Source

Combinators

Since v2.0.0

Iterates over each element of a Chunk and applies a function to it.

Details

This function processes every element of the given Chunk, calling the provided function f on each element. It does not return a new value; instead, it is primarily used for side effects, such as logging or accumulating data in an external variable.

Signature

declare const forEach: {
<A, B>(f: (a: A, index: number) => B): (self: Chunk<A>) => void;
<A, B>(self: Chunk<A>, f: (a: A, index: number) => B): void;
}

Example Iterating over chunk values

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
const values: Array<string> = []
Chunk.forEach(chunk, (n) => values.push(`Value: ${n}`))
values // => ["Value: 1", "Value: 2", "Value: 3", "Value: 4"]
// With index parameter
const indexed: Array<string> = []
Chunk.forEach(chunk, (n, i) => indexed.push(`Index ${i}: ${n}`))
indexed // => ["Index 0: 1", "Index 1: 2", "Index 2: 3", "Index 3: 4"]

Combining

Since v2.0.0

Appends the specified element to the end of the Chunk.

When to use

Use to add one element after the existing chunk elements and return a NonEmptyChunk.

See

  • prepend for adding one element before the existing elements
  • appendAll for appending all elements from another chunk

Signature

declare const append: {
<A2>(a: A2): <A>(self: Chunk<A>) => NonEmptyChunk<A2 | A>;
<A, A2>(self: Chunk<A>, a: A2): NonEmptyChunk<A | A2>;
}

Example Appending an element

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
Chunk.toArray(Chunk.append(chunk, 4)) // => [1, 2, 3, 4]
// Appending to empty chunk
const emptyChunk = Chunk.empty<number>()
Chunk.toArray(Chunk.append(emptyChunk, 42)) // => [42]

Concatenates two chunks, combining their elements. If either chunk is non-empty, the result is also a non-empty chunk.

When to use

Use to concatenate two chunks when the second chunk's elements should come after the first.

See

  • prependAll for concatenating chunks in the opposite order
  • append for adding a single element to the end

Signature

declare const appendAll: {
<S extends Chunk<any>, T extends Chunk<any>>(that: T): (self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: Chunk<A>, that: NonEmptyChunk<B>): NonEmptyChunk<A | B>;
<A, B>(self: NonEmptyChunk<A>, that: Chunk<B>): NonEmptyChunk<A | B>;
<A, B>(self: Chunk<A>, that: Chunk<B>): Chunk<A | B>;
}

Example Appending all elements

import { Chunk } from "effect"
Chunk.make(1, 2).pipe(
Chunk.appendAll(Chunk.make("a", "b")),
Chunk.toArray
) // => [1, 2, "a", "b"]
Since v2.0.0

Prepends an element to the front of a Chunk, creating a new NonEmptyChunk.

Signature

declare const prepend: {
<B>(elem: B): <A>(self: Chunk<A>) => NonEmptyChunk<B | A>;
<A, B>(self: Chunk<A>, elem: B): NonEmptyChunk<A | B>;
}

Example Prepending an element

import { Chunk } from "effect"
const chunk = Chunk.make(2, 3, 4)
Chunk.toArray(Chunk.prepend(chunk, 1)) // => [1, 2, 3, 4]
// Prepending to empty chunk
const emptyChunk = Chunk.empty<string>()
Chunk.toArray(Chunk.prepend(emptyChunk, "first")) // => ["first"]

Prepends the specified prefix chunk to the beginning of the specified chunk. If either chunk is non-empty, the result is also a non-empty chunk.

Signature

declare const prependAll: {
<S extends Chunk<any>, T extends Chunk<any>>(that: T): (self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: Chunk<A>, that: NonEmptyChunk<B>): NonEmptyChunk<A | B>;
<A, B>(self: NonEmptyChunk<A>, that: Chunk<B>): NonEmptyChunk<A | B>;
<A, B>(self: Chunk<A>, that: Chunk<B>): Chunk<A | B>;
}

Example Prepending all elements

import { Chunk } from "effect"
Chunk.make(1, 2).pipe(
Chunk.prependAll(Chunk.make("a", "b")),
Chunk.toArray
) // => ["a", "b", 1, 2]

Constructors

Since v2.0.0

Creates an empty Chunk.

Signature

declare const empty: <A = never>() => Chunk<A>

Example Creating an empty chunk

import { Chunk } from "effect"
Chunk.size(Chunk.empty()) // => 0

Creates a new Chunk from an iterable collection of values.

Signature

declare function fromIterable<A>(self: Iterable<A>): Chunk<A>

Example Creating chunks from iterables

import { Chunk } from "effect"
Chunk.toArray(Chunk.fromIterable([1, 2, 3])) // => [1, 2, 3]
Since v2.0.0

Builds a NonEmptyChunk from an non-empty collection of elements.

Signature

declare function make<As extends readonly [any, any]>(...as: As): NonEmptyChunk<As[number]>

Example Creating a non-empty chunk

import { Chunk } from "effect"
Chunk.toArray(Chunk.make(1, 2, 3, 4)) // => [1, 2, 3, 4]
Since v2.0.0

Returns a non-empty Chunk of length n with element i initialized by f(i).

Details

n is rounded down and normalized to an integer greater than or equal to 1. NaN is treated as 1.

Signature

declare const makeBy: {
<A>(f: (i: number) => A): (n: number) => NonEmptyChunk<A>;
<A>(n: number, f: (i: number) => A): NonEmptyChunk<A>;
}

Example Generating chunks from indices

import { Chunk } from "effect"
Chunk.toArray(Chunk.makeBy(5, (i) => i * 2)) // => [0, 2, 4, 6, 8]
Since v2.0.0

Builds a NonEmptyChunk from a single element.

Signature

declare function of<A>(a: A): NonEmptyChunk<A>

Example Creating a single-element chunk

import { Chunk } from "effect"
Chunk.toArray(Chunk.of("hello")) // => ["hello"]
Since v2.0.0

Creates a non-empty Chunk of consecutive integers from start through end, inclusive.

Details

If start is greater than end, returns a single-element chunk containing start.

Signature

declare function range(start: number, end: number): NonEmptyChunk<number>

Example Creating a range

import { Chunk } from "effect"
Chunk.toArray(Chunk.range(1, 5)) // => [1, 2, 3, 4, 5]

Converting

Since v2.0.0

Converts a Chunk into an Array. If the provided Chunk is non-empty (NonEmptyChunk), the function will return a NonEmptyArray, ensuring the non-empty property is preserved.

Signature

declare const toArray: <S extends Chunk<any>>(self: S) => S extends NonEmptyChunk<any> ? RA.NonEmptyArray<Chunk.Infer<S>> : Array<Chunk.Infer<S>>

Example Converting chunks to mutable arrays

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const array = Chunk.toArray(chunk)
array // => [1, 2, 3]
Array.isArray(array) // => true
// With empty chunk
Chunk.toArray(Chunk.empty<number>()) // => []

Converts a Chunk into a ReadonlyArray. If the provided Chunk is non-empty (NonEmptyChunk), the function will return a NonEmptyReadonlyArray, ensuring the non-empty property is preserved.

Signature

declare const toReadonlyArray: <S extends Chunk<any>>(self: S) => S extends NonEmptyChunk<any> ? RA.NonEmptyReadonlyArray<Chunk.Infer<S>> : ReadonlyArray<Chunk.Infer<S>>

Example Converting chunks to readonly arrays

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const readonlyArray = Chunk.toReadonlyArray(chunk)
readonlyArray // => [1, 2, 3]
// The result is read-only, modifications would cause TypeScript errors
// readonlyArray[0] = 10 // TypeScript error
// With empty chunk
Chunk.toReadonlyArray(Chunk.empty<number>()) // => []

Deduplication

Since v2.0.0

Removes duplicate elements from a Chunk, preserving the first occurrence of each value.

Signature

declare function dedupe<A>(self: Chunk<A>): Chunk<A>

Example Removing duplicate values

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 2, 3, 1, 4, 3)
Chunk.toArray(Chunk.dedupe(chunk)) // => [1, 2, 3, 4]
// Empty chunk
const empty = Chunk.empty<number>()
Chunk.toArray(Chunk.dedupe(empty)) // => []
// No duplicates
const unique = Chunk.make(1, 2, 3)
Chunk.toArray(Chunk.dedupe(unique)) // => [1, 2, 3]

Filtering

Since v2.0.0

Filters out optional values

Signature

declare function compact<A>(self: Chunk<Option<A>>): Chunk<A>

Example Compacting optional values

import { Chunk, Option } from "effect"
const chunk = Chunk.make(Option.some(1), Option.none(), Option.some(3))
Chunk.toArray(Chunk.compact(chunk)) // => [1, 3]

Deduplicates adjacent elements that are identical.

Signature

declare function dedupeAdjacent<A>(self: Chunk<A>): Chunk<A>

Example Removing adjacent duplicates

import { Chunk } from "effect"
const chunk = Chunk.make(1, 1, 2, 2, 2, 3, 1, 1)
Chunk.toArray(Chunk.dedupeAdjacent(chunk)) // => [1, 2, 3, 1]
// Only removes adjacent duplicates, not all duplicates
const mixed = Chunk.make("a", "a", "b", "a", "a")
Chunk.toArray(Chunk.dedupeAdjacent(mixed)) // => ["a", "b", "a"]

Creates a Chunk of values not included in the other given Chunk. The order and references of result values are determined by the first Chunk.

Signature

declare const difference: {
<A>(that: Chunk<A>): (self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, that: Chunk<A>): Chunk<A>;
}

Example Computing chunk difference

import { Chunk } from "effect"
const chunk1 = Chunk.make(1, 2, 3, 4, 5)
const chunk2 = Chunk.make(3, 4, 6, 7)
Chunk.toArray(Chunk.difference(chunk1, chunk2)) // => [1, 2, 5]
// String difference
const words1 = Chunk.make("apple", "banana", "cherry")
const words2 = Chunk.make("banana", "grape")
Chunk.toArray(Chunk.difference(words1, words2)) // => ["apple", "cherry"]
// Empty second chunk returns original
Chunk.toArray(Chunk.difference(chunk1, Chunk.empty<number>())) // => [1, 2, 3, 4, 5]

Creates a Chunk of values not included in the other given Chunk using the provided isEquivalent function. The order and references of result values are determined by the first Chunk.

Signature

declare function differenceWith<A>(isEquivalent: (self: A, that: A) => boolean): {
(that: Chunk<A>): (self: Chunk<A>) => Chunk<A>;
(self: Chunk<A>, that: Chunk<A>): Chunk<A>;
}

Example Computing difference with custom equivalence

import { Chunk } from "effect"
const chunk1 = Chunk.make({ id: 1, name: "Alice" }, { id: 2, name: "Bob" })
const chunk2 = Chunk.make({ id: 1, name: "Alice" }, { id: 3, name: "Charlie" })
// Custom equivalence by id
const byId = Chunk.differenceWith<{ id: number; name: string }>((a, b) =>
a.id === b.id
)
Chunk.toArray(byId(chunk1, chunk2)) // => [{ id: 2, name: "Bob" }]
// String comparison case-insensitive
const words1 = Chunk.make("Apple", "Banana", "Cherry")
const words2 = Chunk.make("apple", "grape")
const caseInsensitive = Chunk.differenceWith<string>((a, b) =>
a.toLowerCase() === b.toLowerCase()
)
Chunk.toArray(caseInsensitive(words1, words2)) // => ["Banana", "Cherry"]
Since v2.0.0

Drops the first up to n elements from the chunk. n is rounded down, with NaN and non-positive values treated as 0.

Signature

declare const drop: {
(n: number): <A>(self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, n: number): Chunk<A>;
}

Example Dropping elements from the start

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.toArray(Chunk.drop(chunk, 2)) // => [3, 4, 5]

Drops the last n elements. n is rounded down, with NaN and non-positive values treated as 0.

Signature

declare const dropRight: {
(n: number): <A>(self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, n: number): Chunk<A>;
}

Example Dropping elements from the end

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.toArray(Chunk.dropRight(chunk, 2)) // => [1, 2, 3]

Drops all elements so long as the predicate returns true.

Signature

declare const dropWhile: {
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Chunk<A>;
}

Example Dropping elements while a predicate matches

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.toArray(Chunk.dropWhile(chunk, (n) => n < 3)) // => [3, 4, 5]
Since v2.0.0

Returns a filtered subset of the elements.

Signature

declare const filter: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Chunk<A>) => Chunk<B>;
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => Chunk<A>;
<A, B>(self: Chunk<A>, refinement: Refinement<A, B>): Chunk<B>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Chunk<A>;
}

Example Filtering values

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6)
const evenNumbers = Chunk.filter(chunk, (n) => n % 2 === 0)
Chunk.toArray(evenNumbers) // => [2, 4, 6]
// With refinement
const mixed = Chunk.make("hello", 42, "world", 100)
const numbers = Chunk.filter(mixed, (x): x is number => typeof x === "number")
Chunk.toArray(numbers) // => [42, 100]

Returns a filtered and mapped subset of the elements.

Signature

declare const filterMap: {
<A, B, X>(f: (input: A, i: number) => Result<B, X>): (self: Chunk<A>) => Chunk<B>;
<A, B, X>(self: Chunk<A>, f: (input: A, i: number) => Result<B, X>): Chunk<B>;
}

Example Filtering and mapping values

import { Chunk, Result } from "effect"
const chunk = Chunk.make("1", "2", "hello", "3", "world")
const numbers = Chunk.filterMap(chunk, (str) => {
const num = parseInt(str)
return isNaN(num) ? Result.failVoid : Result.succeed(num)
})
Chunk.toArray(numbers) // => [1, 2, 3]
// With index parameter
const evenIndexNumbers = Chunk.filterMap(chunk, (str, i) => {
const num = parseInt(str)
return isNaN(num) || i % 2 !== 0 ? Result.failVoid : Result.succeed(num)
})
Chunk.toArray(evenIndexNumbers) // => [1]

Transforms all elements of the chunk for as long as the specified function succeeds.

Signature

declare const filterMapWhile: {
<A, B, X>(f: Filter<A, B, X>): (self: Chunk<A>) => Chunk<B>;
<A, B, X>(self: Chunk<A>, f: Filter<A, B, X>): Chunk<B>;
}

Example Filtering and mapping while values match

import { Chunk, Result } from "effect"
const chunk = Chunk.make("1", "2", "hello", "3", "4")
Chunk.toArray(Chunk.filterMapWhile(chunk, (s) => {
const n = Number(s)
return Number.isNaN(n) ? Result.failVoid : Result.succeed(n)
})) // => [1, 2]
Chunk.toArray(Chunk.filterMap(chunk, (s) => {
const n = Number(s)
return Number.isNaN(n) ? Result.failVoid : Result.succeed(n)
})) // => [1, 2, 3, 4]

Splits a chunk using a Filter into successes and failures.

Details

Returns [passes, fails]. The filter receives (element, index).

Signature

declare const partition: {
<A, Pass, Fail>(f: (input: NoInfer<A>, i: number) => Result<Pass, Fail>): (self: Chunk<A>) => [passes: Chunk<Pass>, fails: Chunk<Fail>];
<A, Pass, Fail>(self: Chunk<A>, f: (input: A, i: number) => Result<Pass, Fail>): [passes: Chunk<Pass>, fails: Chunk<Fail>];
}

Example Partitioning with a Result

import { Chunk, Result } from "effect"
const [passes, fails] = Chunk.partition(Chunk.make(1, -2, 3), (n, i) =>
n > 0 ? Result.succeed(n + i) : Result.fail(`negative:${n}`)
)
Chunk.toArray(passes) // => [1, 5]
Chunk.toArray(fails) // => ["negative:-2"]
Since v2.0.0

Separates a chunk of Result values into a chunk of successes and a chunk of failures.

Details

The returned tuple is [successes, failures], preserving the original order within each side.

Signature

declare function separate<A, B>(self: Chunk<Result<B, A>>): [Chunk<B>, Chunk<A>]

Example Separating successes and failures

import { Chunk, Result } from "effect"
const chunk = Chunk.make(
Result.succeed(1),
Result.fail("error1"),
Result.succeed(2),
Result.fail("error2"),
Result.succeed(3)
)
const [values, errors] = Chunk.separate(chunk)
Chunk.toArray(values) // => [1, 2, 3]
Chunk.toArray(errors) // => ["error1", "error2"]
// All successes
const allSuccesses = Chunk.make(Result.succeed(1), Result.succeed(2))
const [allValues, noErrors] = Chunk.separate(allSuccesses)
Chunk.toArray(allValues) // => [1, 2]
Chunk.toArray(noErrors) // => []
Since v2.0.0

Takes the first up to n elements from the chunk. n is rounded down, with NaN and non-positive values treated as 0.

Signature

declare const take: {
(n: number): <A>(self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, n: number): Chunk<A>;
}

Example Taking elements from the start

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.toArray(Chunk.take(chunk, 3)) // => [1, 2, 3]

Takes the last n elements. n is rounded down, with NaN and non-positive values treated as 0.

Signature

declare const takeRight: {
(n: number): <A>(self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, n: number): Chunk<A>;
}

Example Taking elements from the end

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6)
Chunk.toArray(Chunk.takeRight(chunk, 3)) // => [4, 5, 6]
// Take more than available
Chunk.toArray(Chunk.takeRight(chunk, 10)) // => [1, 2, 3, 4, 5, 6]
// Take zero
Chunk.toArray(Chunk.takeRight(chunk, 0)) // => []

Takes all elements so long as the predicate returns true.

Signature

declare const takeWhile: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Chunk<A>) => Chunk<B>;
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => Chunk<A>;
<A, B>(self: Chunk<A>, refinement: Refinement<A, B>): Chunk<B>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Chunk<A>;
}

Example Taking elements while a predicate matches

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 3, 2, 1)
Chunk.toArray(Chunk.takeWhile(chunk, (n) => n < 4)) // => [1, 2, 3]
// Empty if first element doesn't match
Chunk.toArray(Chunk.takeWhile(chunk, (n) => n > 5)) // => []
// Takes all if all match
const small = Chunk.make(1, 2, 3)
Chunk.toArray(Chunk.takeWhile(small, (n) => n < 10)) // => [1, 2, 3]

Folding

Since v2.0.0

Joins the elements together with "sep" in the middle.

Signature

declare const join: {
(sep: string): (self: Chunk<string>) => string;
(self: Chunk<string>, sep: string): string;
}

Example Joining chunks into a string

import { Chunk } from "effect"
const chunk = Chunk.make("apple", "banana", "cherry")
Chunk.join(chunk, ", ") // => "apple, banana, cherry"
// With different separator
Chunk.join(chunk, " | ") // => "apple | banana | cherry"
// Empty chunk
Chunk.join(Chunk.empty<string>(), ", ") // => ""
// Single element
Chunk.join(Chunk.make("hello"), ", ") // => "hello"
Since v2.0.0

Maps over the chunk statefully, producing new elements of type B.

Signature

declare const mapAccum: {
<S, A, B>(s: S, f: (s: S, a: A) => readonly [S, B]): (self: Chunk<A>) => [S, Chunk<B>];
<S, A, B>(self: Chunk<A>, s: S, f: (s: S, a: A) => readonly [S, B]): [S, Chunk<B>];
}

Example Mapping with accumulated state

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
const [finalState, mapped] = Chunk.mapAccum(chunk, 0, (state, current) => [
state + current, // accumulate sum
state + current // output running sum
])
finalState // => 15
Chunk.toArray(mapped) // => [1, 3, 6, 10, 15]
// Building a string with indices
const words = Chunk.make("hello", "world", "effect")
const [count, indexed] = Chunk.mapAccum(words, 0, (index, word) => [
index + 1,
`${index}: ${word}`
])
count // => 3
Chunk.toArray(indexed) // => ["0: hello", "1: world", "2: effect"]
Since v2.0.0

Reduces the elements of a chunk from left to right.

Signature

declare const reduce: {
<B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Chunk<A>) => B;
<A, B>(self: Chunk<A>, b: B, f: (b: B, a: A, i: number) => B): B;
}

Example Reducing from the left

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.reduce(chunk, 0, (acc, n) => acc + n) // => 15
// String concatenation with index
const words = Chunk.make("a", "b", "c")
Chunk.reduce(words, "", (acc, word, i) => acc + `${i}:${word} `).trimEnd() // => "0:a 1:b 2:c"
// Find maximum
Chunk.reduce(chunk, -Infinity, (acc, n) => Math.max(acc, n)) // => 5

Reduces the elements of a chunk from right to left.

Signature

declare const reduceRight: {
<B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Chunk<A>) => B;
<A, B>(self: Chunk<A>, b: B, f: (b: B, a: A, i: number) => B): B;
}

Example Reducing from the right

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
Chunk.reduceRight(chunk, 0, (acc, n) => acc + n) // => 10
// String building (right to left)
const words = Chunk.make("a", "b", "c")
Chunk.reduceRight(
words,
"",
(acc, word, i) => acc + `${i}:${word} `
).trim() // => "2:c 1:b 0:a"
// Subtract from right to left
Chunk.reduceRight(chunk, 0, (acc, n) => n - acc) // => -2

Getters

Since v2.0.0

Gets the value at an index in a Chunk safely, returning None when the index is out of bounds.

Signature

declare const get: {
(index: number): <A>(self: Chunk<A>) => Option<A>;
<A>(self: Chunk<A>, index: number): Option<A>;
}

Example Accessing elements safely

import { Chunk, Option } from "effect"
const chunk = Chunk.make("a", "b", "c", "d")
Chunk.get(chunk, 1) // => Option.some("b")
Chunk.get(chunk, 10) // => Option.none()
Chunk.get(chunk, -1) // => Option.none()
// Using pipe syntax
chunk.pipe(Chunk.get(2)) // => Option.some("c")

Returns the first element of this non empty chunk.

Signature

declare const headNonEmpty: <A>(self: NonEmptyChunk<A>) => A

Example Getting the first element of a non-empty chunk

import { Chunk } from "effect"
const nonEmptyChunk = Chunk.make(1, 2, 3, 4)
Chunk.headNonEmpty(nonEmptyChunk) // => 1
const singleElement = Chunk.make("hello")
Chunk.headNonEmpty(singleElement) // => "hello"
// Type safety: this function only accepts NonEmptyChunk
// Chunk.headNonEmpty(Chunk.empty()) // TypeScript error
Since v2.0.0

Returns the last element of this chunk safely if it exists.

Signature

declare function last<A>(self: Chunk<A>): Option<A>

Example Getting the last element

import { Chunk, Option } from "effect"
Chunk.last(Chunk.empty()) // => Option.none()
Chunk.last(Chunk.make(1, 2, 3)) // => Option.some(3)

Returns the last element of this non empty chunk.

Signature

declare const lastNonEmpty: <A>(self: NonEmptyChunk<A>) => A

Example Getting the last element of a non-empty chunk

import { Chunk } from "effect"
const nonEmptyChunk = Chunk.make(1, 2, 3, 4)
Chunk.lastNonEmpty(nonEmptyChunk) // => 4
const singleElement = Chunk.make("hello")
Chunk.lastNonEmpty(singleElement) // => "hello"
// Type safety: this function only accepts NonEmptyChunk
// Chunk.lastNonEmpty(Chunk.empty()) // TypeScript error
Since v2.0.0

Retrieves the size of the chunk.

Signature

declare function size<A>(self: Chunk<A>): number

Example Getting chunk size

import { Chunk } from "effect"
Chunk.size(Chunk.make(1, 2, 3)) // => 3
Since v2.0.0

Returns every element after the first safely, or None when the chunk is empty.

Signature

declare function tail<A>(self: Chunk<A>): Option<Chunk<A>>

Example Getting the tail safely

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
Chunk.tail(chunk) // => Option.some(Chunk.make(2, 3, 4))
const singleElement = Chunk.make(1)
Chunk.tail(singleElement) // => Option.some(Chunk.empty())
Chunk.tail(Chunk.empty<number>()) // => Option.none()

Returns every element after the first from a non-empty chunk.

Signature

declare function tailNonEmpty<A>(self: NonEmptyChunk<A>): Chunk<A>

Example Getting the tail of a non-empty chunk

import { Chunk } from "effect"
const nonEmptyChunk = Chunk.make(1, 2, 3, 4)
Chunk.toArray(Chunk.tailNonEmpty(nonEmptyChunk)) // => [2, 3, 4]
const singleElement = Chunk.make(1)
Chunk.toArray(Chunk.tailNonEmpty(singleElement)) // => []
// Type safety: this function only accepts NonEmptyChunk
// Chunk.tailNonEmpty(Chunk.empty()) // TypeScript error

Guards

Since v2.0.0

Checks whether a predicate holds true for every Chunk element.

Signature

declare const every: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Chunk<A>) => self is Chunk<B>;
<A>(predicate: Predicate<A>): (self: Chunk<A>) => boolean;
<A, B>(self: Chunk<A>, refinement: Refinement<A, B>): self is Chunk<B>;
<A>(self: Chunk<A>, predicate: Predicate<A>): boolean;
}

Example Checking every element

import { Chunk } from "effect"
const allPositive = Chunk.make(1, 2, 3, 4, 5)
Chunk.every(allPositive, (n) => n > 0) // => true
Chunk.every(allPositive, (n) => n > 3) // => false
// Empty chunk returns true
Chunk.every(Chunk.empty<number>(), (n) => n > 0) // => true
// Type refinement
const mixed = Chunk.make(1, 2, 3)
if (Chunk.every(mixed, (x): x is number => typeof x === "number")) {
// mixed is now typed as Chunk<number>
}
Since v2.0.0

Checks whether u is a Chunk<unknown>

Signature

declare const isChunk: {
<A>(u: Iterable<A>): u is Chunk<A>;
(u: unknown): u is Chunk<unknown>;
}

Example Checking for chunks

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const array = [1, 2, 3]
Chunk.isChunk(chunk) // => true
Chunk.isChunk(array) // => false
Chunk.isChunk("string") // => false

Determines if the chunk is not empty.

Signature

declare function isNonEmpty<A>(self: Chunk<A>): self is NonEmptyChunk<A>

Example Checking for non-empty chunks

import { Chunk } from "effect"
Chunk.isNonEmpty(Chunk.empty()) // => false
Chunk.isNonEmpty(Chunk.make(1, 2, 3)) // => true
Since v2.0.0

Checks whether a predicate holds true for some Chunk element.

Signature

declare const some: {
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => self is NonEmptyChunk<A>;
<A>(self: Chunk<A>, predicate: Predicate<A>): self is NonEmptyChunk<A>;
}

Example Checking for some matching element

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.some(chunk, (n) => n > 4) // => true
Chunk.some(chunk, (n) => n > 10) // => false
// Empty chunk returns false
Chunk.some(Chunk.empty<number>(), (n) => n > 0) // => false
// Check for specific value
const words = Chunk.make("apple", "banana", "cherry")
Chunk.some(words, (word) => word.includes("ban")) // => true

Instances

Creates an Equivalence for chunks that compares chunk lengths and then compares corresponding elements with the provided element equivalence.

Signature

declare function makeEquivalence<A>(isEquivalent: Equivalence<A>): Equivalence<Chunk<A>>

Example Comparing chunks for equivalence

import { Chunk, Equivalence } from "effect"
const chunk1 = Chunk.make(1, 2, 3)
const chunk2 = Chunk.make(1, 2, 3)
const chunk3 = Chunk.make(1, 2, 4)
const eq = Chunk.makeEquivalence(Equivalence.strictEqual<number>())
eq(chunk1, chunk2) // => true
eq(chunk1, chunk3) // => false

Mapping

Since v2.0.0

Transforms the elements of a chunk using the specified mapping function. If the input chunk is non-empty, the resulting chunk will also be non-empty.

Signature

declare const map: {
<S extends Chunk<any>, B>(f: (a: Infer<S>, i: number) => B): (self: S) => With<S, B>;
<A, B>(self: NonEmptyChunk<A>, f: (a: A, i: number) => B): NonEmptyChunk<B>;
<A, B>(self: Chunk<A>, f: (a: A, i: number) => B): Chunk<B>;
}

Example Mapping values

import { Chunk } from "effect"
Chunk.toArray(Chunk.map(Chunk.make(1, 2), (n) => n + 1)) // => [2, 3]

Models

Chunk

interface
Since v2.0.0

A Chunk is an immutable, ordered collection optimized for efficient concatenation and access patterns.

Signature

interface Chunk<out A> extends Iterable<A>, Equal, Pipeable, Inspectable {
readonly "~effect/Chunk": {
readonly _A: Covariant<A>;
};
backing: Backing<A>;
depth: number;
left: Chunk<A>;
readonly length: number;
right: Chunk<A>;
}

Example Inspecting chunk values

import { Chunk } from "effect"
const chunk: Chunk.Chunk<number> = Chunk.make(1, 2, 3)
chunk.length // => 3
Chunk.toArray(chunk) // => [1, 2, 3]

NonEmptyChunk

interface
Since v2.0.0

A non-empty Chunk guaranteed to contain at least one element.

Signature

interface NonEmptyChunk<out A> extends Chunk<A>, NonEmptyIterable<A> {}

Example Working with non-empty chunks

import { Chunk } from "effect"
const nonEmptyChunk: Chunk.NonEmptyChunk<number> = Chunk.make(1, 2, 3)
Chunk.headNonEmpty(nonEmptyChunk) // => 1
Chunk.lastNonEmpty(nonEmptyChunk) // => 3

Other

Since v2.0.0

A namespace containing utility types for Chunk operations.

Example Working with Chunk utility types

import type { Chunk } from "effect"
// Extract the element type from a Chunk
declare const chunk: Chunk.Chunk<string>
type ElementType = Chunk.Chunk.Infer<typeof chunk> // string
// Create a preserving non-emptiness
declare const nonEmptyChunk: Chunk.NonEmptyChunk<number>
type WithString = Chunk.Chunk.With<typeof nonEmptyChunk, string> // Chunk.NonEmptyChunk<string>

Predicates

Since v2.0.0

Returns a function that checks if a Chunk contains a given value using the default Equivalence.

Signature

declare const contains: {
<A>(a: A): (self: Chunk<A>) => boolean;
<A>(self: Chunk<A>, a: A): boolean;
}

Example Checking membership

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.contains(chunk, 3) // => true
Chunk.contains(chunk, 6) // => false
// Works with strings
const words = Chunk.make("apple", "banana", "cherry")
Chunk.contains(words, "banana") // => true
Chunk.contains(words, "grape") // => false
// Empty chunk
Chunk.contains(Chunk.empty<number>(), 1) // => false

Returns a function that checks if a Chunk contains a given value using a provided isEquivalent function.

Signature

declare const containsWith: <A>(isEquivalent: (self: A, that: A) => boolean) => {
(a: A): (self: Chunk<A>) => boolean;
(self: Chunk<A>, a: A): boolean;
}

Example Checking membership with custom equivalence

import { Chunk } from "effect"
const chunk = Chunk.make({ id: 1, name: "Alice" }, { id: 2, name: "Bob" })
// Custom equivalence by id
const containsById = Chunk.containsWith<{ id: number; name: string }>((a, b) =>
a.id === b.id
)
containsById(chunk, { id: 1, name: "Different" }) // => true
containsById(chunk, { id: 3, name: "Charlie" }) // => false
// Case-insensitive string comparison
const words = Chunk.make("Apple", "Banana", "Cherry")
const containsCaseInsensitive = Chunk.containsWith<string>((a, b) =>
a.toLowerCase() === b.toLowerCase()
)
containsCaseInsensitive(words, "apple") // => true
containsCaseInsensitive(words, "grape") // => false
Since v2.0.0

Determines if the chunk is empty.

Signature

declare function isEmpty<A>(self: Chunk<A>): boolean

Example Checking for empty chunks

import { Chunk } from "effect"
Chunk.isEmpty(Chunk.empty()) // => true
Chunk.isEmpty(Chunk.make(1, 2, 3)) // => false

Searching

Returns the first element that satisfies the specified predicate, or None if no such element exists.

Signature

declare const findFirst: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Chunk<A>) => Option<B>;
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => Option<A>;
<A, B>(self: Chunk<A>, refinement: Refinement<A, B>): Option<B>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Option<A>;
}

Example Finding the first matching element

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.findFirst(chunk, (n) => n > 3) // => Option.some(4)
// No match found
Chunk.findFirst(chunk, (n) => n > 10) // => Option.none()
// With type refinement
const mixed = Chunk.make(1, "hello", 2, "world", 3)
const firstString = Chunk.findFirst(
mixed,
(x): x is string => typeof x === "string"
)
firstString // => Option.some("hello")

Returns the first index for which a predicate holds.

Signature

declare const findFirstIndex: {
<A>(predicate: Predicate<A>): (self: Chunk<A>) => Option<number>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Option<number>;
}

Example Finding the first matching index

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.findFirstIndex(chunk, (n) => n > 3) // => Option.some(3)
// No match found
Chunk.findFirstIndex(chunk, (n) => n > 10) // => Option.none()
// Find first even number
Chunk.findFirstIndex(chunk, (n) => n % 2 === 0) // => Option.some(1)
Since v2.0.0

Finds the last element for which a predicate holds.

Signature

declare const findLast: {
<A, B>(refinement: Refinement<NoInfer<A>, B>): (self: Chunk<A>) => Option<B>;
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => Option<A>;
<A, B>(self: Chunk<A>, refinement: Refinement<A, B>): Option<B>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Option<A>;
}

Example Finding the last matching element

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.findLast(chunk, (n) => n < 4) // => Option.some(3)
// No match found
Chunk.findLast(chunk, (n) => n > 10) // => Option.none()
// Find last even number
Chunk.findLast(chunk, (n) => n % 2 === 0) // => Option.some(4)

Returns the last index for which a predicate holds.

Signature

declare const findLastIndex: {
<A>(predicate: Predicate<A>): (self: Chunk<A>) => Option<number>;
<A>(self: Chunk<A>, predicate: Predicate<A>): Option<number>;
}

Example Finding the last matching index

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
Chunk.findLastIndex(chunk, (n) => n < 4) // => Option.some(2)
// No match found
Chunk.findLastIndex(chunk, (n) => n > 10) // => Option.none()
// Find last even number index
Chunk.findLastIndex(chunk, (n) => n % 2 === 0) // => Option.some(3)

Sequencing

Since v2.0.0

Applies a function to each element in a chunk and returns a new chunk containing the concatenated mapped elements.

Signature

declare const flatMap: {
<S extends Chunk<any>, T extends Chunk<any>>(f: (a: Infer<S>, i: number) => T): (self: S) => AndNonEmpty<S, T, Infer<T>>;
<A, B>(self: NonEmptyChunk<A>, f: (a: A, i: number) => NonEmptyChunk<B>): NonEmptyChunk<B>;
<A, B>(self: Chunk<A>, f: (a: A, i: number) => Chunk<B>): Chunk<B>;
}

Example Flat mapping chunks

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const duplicated = Chunk.flatMap(chunk, (n) => Chunk.make(n, n))
Chunk.toArray(duplicated) // => [1, 1, 2, 2, 3, 3]
// Flattening nested arrays
const words = Chunk.make("hello", "world")
const letters = Chunk.flatMap(
words,
(word) => Chunk.fromIterable(word.split(""))
)
Chunk.toArray(letters).join("") // => "helloworld"
// With index parameter
const indexed = Chunk.flatMap(chunk, (n, i) => Chunk.make(n + i))
Chunk.toArray(indexed) // => [1, 3, 5]
Since v2.0.0

Flattens a chunk of chunks into a single chunk by concatenating all chunks.

Signature

declare const flatten: <S extends Chunk<Chunk<any>>>(self: S) => Chunk.Flatten<S>

Example Flattening nested chunks

import { Chunk } from "effect"
const nested = Chunk.make(
Chunk.make(1, 2),
Chunk.make(3, 4, 5),
Chunk.make(6)
)
Chunk.toArray(Chunk.flatten(nested)) // => [1, 2, 3, 4, 5, 6]
// With empty chunks
const withEmpty = Chunk.make(
Chunk.make(1, 2),
Chunk.empty<number>(),
Chunk.make(3, 4)
)
Chunk.toArray(Chunk.flatten(withEmpty)) // => [1, 2, 3, 4]

Set Operations

Creates a Chunk of values that are included in both chunks.

Details

The order and references of result values are determined by the first chunk.

Signature

declare const intersection: {
<A>(that: Chunk<A>): <B>(self: Chunk<B>) => Chunk<A & B>;
<A, B>(self: Chunk<A>, that: Chunk<B>): Chunk<A & B>;
}

Example Intersecting chunks

import { Chunk } from "effect"
const chunk1 = Chunk.make(1, 2, 3, 4)
const chunk2 = Chunk.make(3, 4, 5, 6)
Chunk.toArray(Chunk.intersection(chunk1, chunk2)) // => [3, 4]
// With strings
const words1 = Chunk.make("hello", "world", "foo")
const words2 = Chunk.make("world", "bar", "foo")
Chunk.toArray(Chunk.intersection(words1, words2)) // => ["world", "foo"]
// No intersection
const chunk3 = Chunk.make(1, 2)
const chunk4 = Chunk.make(3, 4)
Chunk.toArray(Chunk.intersection(chunk3, chunk4)) // => []
Since v2.0.0

Creates a Chunks of unique values, in order, from all given Chunks.

Signature

declare const union: {
<A>(that: Chunk<A>): <B>(self: Chunk<B>) => Chunk<A | B>;
<A, B>(self: Chunk<A>, that: Chunk<B>): Chunk<A | B>;
}

Example Unioning chunks

import { Chunk } from "effect"
const chunk1 = Chunk.make(1, 2, 3)
const chunk2 = Chunk.make(3, 4, 5)
Chunk.toArray(Chunk.union(chunk1, chunk2)) // => [1, 2, 3, 4, 5]
// Handles duplicates within the same chunk
const withDupes1 = Chunk.make(1, 1, 2)
const withDupes2 = Chunk.make(2, 3, 3)
Chunk.toArray(Chunk.union(withDupes1, withDupes2)) // => [1, 2, 3]

Sorting

Since v2.0.0

Sorts the elements of a Chunk in increasing order, creating a new Chunk.

Signature

declare const sort: {
<B>(O: Order<B>): <A>(self: Chunk<A>) => Chunk<A>;
<A, B>(self: Chunk<A>, O: Order<B>): Chunk<A>;
}

Example Sorting chunks

import { Chunk, Order } from "effect"
const numbers = Chunk.make(3, 1, 4, 1, 5, 9, 2, 6)
Chunk.toArray(Chunk.sort(numbers, Order.Number)) // => [1, 1, 2, 3, 4, 5, 6, 9]
// Reverse order
Chunk.toArray(Chunk.sort(numbers, Order.flip(Order.Number))) // => [9, 6, 5, 4, 3, 2, 1, 1]
// String sorting
const words = Chunk.make("banana", "apple", "cherry")
Chunk.toArray(Chunk.sort(words, Order.String)) // => ["apple", "banana", "cherry"]
Since v2.0.0

Sorts the elements of a Chunk based on a projection function.

Signature

declare const sortWith: {
<A, B>(f: (a: A) => B, order: Order<B>): (self: Chunk<A>) => Chunk<A>;
<A, B>(self: Chunk<A>, f: (a: A) => B, order: Order<B>): Chunk<A>;
}

Example Sorting chunks by a derived value

import { Chunk, Order } from "effect"
const people = Chunk.make(
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 35 }
)
// Sort by age
const byAge = Chunk.sortWith(people, (person) => person.age, Order.Number)
Chunk.toArray(byAge).map((person) => person.name) // => ["Bob", "Alice", "Charlie"]
// Sort by name
const byName = Chunk.sortWith(people, (person) => person.name, Order.String)
Chunk.toArray(byName).map((person) => person.name) // => ["Alice", "Bob", "Charlie"]
// Sort by string length
const words = Chunk.make("a", "abc", "ab")
Chunk.toArray(Chunk.sortWith(words, (word) => word.length, Order.Number)) // => ["a", "ab", "abc"]

Splitting

Since v2.0.0

Groups elements in chunks of up to n elements.

When to use

Use to divide a chunk into ordered, non-overlapping chunks with at most n elements each.

Details

n is rounded down and normalized to at least 1. The final chunk may contain fewer than n elements. Empty input produces an empty chunk of chunks.

Gotchas

NaN and values of n less than or equal to zero produce singleton chunks.

See

  • split for splitting into a target number of chunks instead of a fixed chunk size

Signature

declare const chunksOf: {
(n: number): <A>(self: Chunk<A>) => Chunk<Chunk<A>>;
<A>(self: Chunk<A>, n: number): Chunk<Chunk<A>>;
}

Example Splitting into fixed-size chunks

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6, 7, 8, 9)
const chunked = Chunk.chunksOf(chunk, 3)
Chunk.toArray(chunked).map(Chunk.toArray) // => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// When length is not evenly divisible
const chunk2 = Chunk.make(1, 2, 3, 4, 5)
const chunked2 = Chunk.chunksOf(chunk2, 2)
Chunk.toArray(chunked2).map(Chunk.toArray) // => [[1, 2], [3, 4], [5]]
Since v2.0.0

Splits a chunk into up to n chunks, distributing elements in order.

Details

n is rounded down and normalized to at least 1, with NaN treated as 1. The chunk size is derived from the input length and normalized count; the final chunk may contain fewer elements than the others.

Signature

declare const split: {
(n: number): <A>(self: Chunk<A>) => Chunk<Chunk<A>>;
<A>(self: Chunk<A>, n: number): Chunk<Chunk<A>>;
}

Example Splitting chunks into groups

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6, 7, 8, 9)
const chunks = Chunk.split(chunk, 3)
Chunk.toArray(chunks).map(Chunk.toArray) // => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// Uneven split
const chunk2 = Chunk.make(1, 2, 3, 4, 5, 6, 7, 8)
const chunks2 = Chunk.split(chunk2, 3)
Chunk.toArray(chunks2).map(Chunk.toArray) // => [[1, 2, 3], [4, 5, 6], [7, 8]]
// Split into 1 chunk
const chunks3 = Chunk.split(chunk, 1)
Chunk.toArray(chunks3).map(Chunk.toArray) // => [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
Since v2.0.0

Returns two splits of this chunk at the specified index.

Signature

declare const splitAt: {
(n: number): <A>(self: Chunk<A>) => [beforeIndex: Chunk<A>, fromIndex: Chunk<A>];
<A>(self: Chunk<A>, n: number): [beforeIndex: Chunk<A>, fromIndex: Chunk<A>];
}

Example Splitting at an index

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6)
const [before, after] = Chunk.splitAt(chunk, 3)
Chunk.toArray(before) // => [1, 2, 3]
Chunk.toArray(after) // => [4, 5, 6]
// Split at index 0
const [empty, all] = Chunk.splitAt(chunk, 0)
Chunk.toArray(empty) // => []
Chunk.toArray(all) // => [1, 2, 3, 4, 5, 6]
// Split beyond length
const [allElements, empty2] = Chunk.splitAt(chunk, 10)
Chunk.toArray(allElements) // => [1, 2, 3, 4, 5, 6]
Chunk.toArray(empty2) // => []

Splits a NonEmptyChunk at n, returning a non-empty prefix and the remaining suffix.

Details

n is rounded down and normalized to at least 1, with NaN treated as 1. If n is greater than or equal to the chunk length, the first result is the original chunk and the second result is empty.

Signature

declare const splitNonEmptyAt: {
(n: number): <A>(self: NonEmptyChunk<A>) => [beforeIndex: NonEmptyChunk<A>, fromIndex: Chunk<A>];
<A>(self: NonEmptyChunk<A>, n: number): [beforeIndex: NonEmptyChunk<A>, fromIndex: Chunk<A>];
}

Example Splitting non-empty chunks at an index

import { Chunk } from "effect"
const nonEmptyChunk = Chunk.make(1, 2, 3, 4, 5, 6)
const [before, after] = Chunk.splitNonEmptyAt(nonEmptyChunk, 3)
Chunk.toArray(before) // => [1, 2, 3]
Chunk.toArray(after) // => [4, 5, 6]
// Split at 1 (minimum)
const [first, rest] = Chunk.splitNonEmptyAt(nonEmptyChunk, 1)
Chunk.toArray(first) // => [1]
Chunk.toArray(rest) // => [2, 3, 4, 5, 6]
// The first part is guaranteed to be NonEmptyChunk
// while the second part may be empty

Splits this chunk on the first element that matches this predicate. Returns a tuple containing two chunks: the first one is before the match, and the second one is from the match onward.

Signature

declare const splitWhere: {
<A>(predicate: Predicate<NoInfer<A>>): (self: Chunk<A>) => [beforeMatch: Chunk<A>, fromMatch: Chunk<A>];
<A>(self: Chunk<A>, predicate: Predicate<A>): [beforeMatch: Chunk<A>, fromMatch: Chunk<A>];
}

Example Splitting at a matching element

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5, 6)
const [before, fromMatch] = Chunk.splitWhere(chunk, (n) => n > 3)
Chunk.toArray(before) // => [1, 2, 3]
Chunk.toArray(fromMatch) // => [4, 5, 6]
// No match found
const [all, empty] = Chunk.splitWhere(chunk, (n) => n > 10)
Chunk.toArray(all) // => [1, 2, 3, 4, 5, 6]
Chunk.toArray(empty) // => []
// Match on first element
const [emptyBefore, allFromFirst] = Chunk.splitWhere(chunk, (n) => n === 1)
Chunk.toArray(emptyBefore) // => []
Chunk.toArray(allFromFirst) // => [1, 2, 3, 4, 5, 6]
Since v2.0.0

Takes a Chunk of pairs and returns two corresponding Chunks.

Details

This function is the reverse of zip.

Signature

declare function unzip<A, B>(self: Chunk<readonly [A, B]>): [Chunk<A>, Chunk<B>]

Example Unzipping pairs

import { Chunk } from "effect"
const pairs = Chunk.make(
[1, "a"] as const,
[2, "b"] as const,
[3, "c"] as const
)
const [numbers, letters] = Chunk.unzip(pairs)
Chunk.toArray(numbers) // => [1, 2, 3]
Chunk.toArray(letters) // => ["a", "b", "c"]
// Empty chunk
const empty = Chunk.empty<[number, string]>()
const [emptyNums, emptyStrs] = Chunk.unzip(empty)
Chunk.toArray(emptyNums) // => []
Chunk.toArray(emptyStrs) // => []

Transforming

Since v2.0.0

Applies a function to the element at the specified index safely, creating a new Chunk, or returns None if the index is out of bounds.

Signature

declare const modify: {
<A, B>(i: number, f: (a: A) => B): (self: Chunk<A>) => Option<Chunk<A | B>>;
<A, B>(self: Chunk<A>, i: number, f: (a: A) => B): Option<Chunk<A | B>>;
}

Example Modifying an element

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
Chunk.modify(chunk, 1, (n) => n * 10) // => Option.some(Chunk.make(1, 20, 3, 4))
// Index out of bounds returns None
chunk.pipe(Chunk.modify(10, (n) => n * 10)) // => Option.none()
// Negative index returns None
chunk.pipe(Chunk.modify(-1, (n) => n * 10)) // => Option.none()
Since v2.0.0

Deletes the element at the specified index, creating a new Chunk.

Signature

declare const remove: {
(i: number): <A>(self: Chunk<A>) => Chunk<A>;
<A>(self: Chunk<A>, i: number): Chunk<A>;
}

Example Removing an element

import { Chunk } from "effect"
const chunk = Chunk.make("a", "b", "c", "d")
Chunk.toArray(Chunk.remove(chunk, 1)) // => ["a", "c", "d"]
// Remove first element
Chunk.toArray(Chunk.remove(chunk, 0)) // => ["b", "c", "d"]
// Index out of bounds returns same chunk
Chunk.toArray(Chunk.remove(chunk, 10)) // => ["a", "b", "c", "d"]
Since v2.0.0

Changes the element at the specified index safely, creating a new Chunk, or returns None if the index is out of bounds.

Signature

declare const replace: {
<B>(i: number, b: B): <A>(self: Chunk<A>) => Option<Chunk<B | A>>;
<A, B>(self: Chunk<A>, i: number, b: B): Option<Chunk<A | B>>;
}

Example Replacing an element

import { Chunk, Option } from "effect"
const chunk = Chunk.make("a", "b", "c", "d")
Chunk.replace(chunk, 1, "X") // => Option.some(Chunk.make("a", "X", "c", "d"))
// Index out of bounds returns None
chunk.pipe(Chunk.replace(10, "Y")) // => Option.none()
// Negative index returns None
chunk.pipe(Chunk.replace(-1, "Z")) // => Option.none()
Since v2.0.0

Reverses the order of elements in a Chunk.

When to use

Use to read or process chunk elements in reverse order.

Details

If the input chunk is a NonEmptyChunk, the reversed chunk is also a NonEmptyChunk.

Signature

declare const reverse: <S extends Chunk<any>>(self: S) => Chunk.With<S, Chunk.Infer<S>>

Example Reversing chunks

import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
Chunk.toArray(Chunk.reverse(chunk)) // => [3, 2, 1]

Unsafe

Wraps an array into a chunk without copying.

When to use

Use when the input array can be shared with the resulting Chunk and avoiding a copy matters.

Gotchas

Mutating the source array after wrapping can mutate the resulting Chunk.

Signature

declare function fromArrayUnsafe<A>(self: readonly Array<A>): Chunk<A>

Example Creating chunks without copying arrays

import { Chunk } from "effect"
const array = [1, 2, 3, 4, 5]
const chunk = Chunk.fromArrayUnsafe(array)
Chunk.toArray(chunk) // => [1, 2, 3, 4, 5]
// Warning: Since this doesn't copy the array, mutations affect the chunk
array[0] = 999
Chunk.toArray(chunk) // => [999, 2, 3, 4, 5]

Wraps a non-empty array into a non-empty chunk without copying.

When to use

Use when the input array is already known to be non-empty, can be shared with the resulting Chunk, and avoiding a copy matters.

Gotchas

Mutating the source array after wrapping can mutate the resulting Chunk.

Signature

declare function fromNonEmptyArrayUnsafe<A>(self: readonly [A, A]): NonEmptyChunk<A>

Example Creating non-empty chunks without copying arrays

import { Array, Chunk } from "effect"
const nonEmptyArray = Array.make(1, 2, 3, 4, 5)
const chunk = Chunk.fromNonEmptyArrayUnsafe(nonEmptyArray)
Chunk.toArray(chunk) // => [1, 2, 3, 4, 5]
// The result is guaranteed to be non-empty
Chunk.isNonEmpty(chunk) // => true

Gets an element at the specified index without returning an Option.

When to use

Use when reading from a Chunk at an index known to be in bounds and direct element access is preferred over handling Option.none.

Gotchas

Throws if the index is out of bounds.

Signature

declare const getUnsafe: {
(index: number): <A>(self: Chunk<A>) => A;
<A>(self: Chunk<A>, index: number): A;
}

Example Accessing elements unsafely

import { Chunk, Option } from "effect"
const chunk = Chunk.make("a", "b", "c", "d")
Chunk.getUnsafe(chunk, 1) // => "b"
Chunk.getUnsafe(chunk, 3) // => "d"
// Use Chunk.get when the index may be out of bounds
Option.isNone(Chunk.get(chunk, 10)) // => true

Returns the first element of this chunk.

When to use

Use when you know the chunk is non-empty and need the first element directly without handling Option.none.

Gotchas

Throws an error if the chunk is empty.

Signature

declare function headUnsafe<A>(self: Chunk<A>): A

Example Getting the first element unsafely

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
Chunk.headUnsafe(chunk) // => 1
const singleElement = Chunk.make("hello")
Chunk.headUnsafe(singleElement) // => "hello"
// Use Chunk.head when the chunk may be empty
Option.isNone(Chunk.head(Chunk.empty())) // => true

Returns the last element of this chunk.

When to use

Use when you know the chunk is non-empty and need the last element directly without handling Option.none.

Gotchas

Throws an error if the chunk is empty.

Signature

declare function lastUnsafe<A>(self: Chunk<A>): A

Example Getting the last element unsafely

import { Chunk, Option } from "effect"
const chunk = Chunk.make(1, 2, 3, 4)
Chunk.lastUnsafe(chunk) // => 4
const singleElement = Chunk.make("hello")
Chunk.lastUnsafe(singleElement) // => "hello"
// Use Chunk.last when the chunk may be empty
Option.isNone(Chunk.last(Chunk.empty())) // => true

Utility Types

Since v2.0.0

Type lambda for Chunk, used for higher-kinded type operations.

Signature

interface ChunkTypeLambda extends TypeLambda {
readonly type: Chunk<unknown>;
}

Example Applying the Chunk type lambda

import type { Chunk, HKT } from "effect"
// Create a Chunk type using the type lambda
type NumberChunk = HKT.Kind<Chunk.ChunkTypeLambda, never, never, never, number>
// Equivalent to: Chunk<number>

Zipping

Since v2.0.0

Zips this chunk pointwise with the specified chunk.

Signature

declare const zip: {
<B>(that: Chunk<B>): <A>(self: Chunk<A>) => Chunk<[A, B]>;
<A, B>(self: Chunk<A>, that: Chunk<B>): Chunk<[A, B]>;
}

Example Zipping chunks

import { Chunk } from "effect"
const numbers = Chunk.make(1, 2, 3)
const letters = Chunk.make("a", "b", "c")
Chunk.toArray(Chunk.zip(numbers, letters)) // => [[1, "a"], [2, "b"], [3, "c"]]
// Different lengths - takes minimum length
const short = Chunk.make(1, 2)
const long = Chunk.make("a", "b", "c", "d")
Chunk.toArray(Chunk.zip(short, long)) // => [[1, "a"], [2, "b"]]
Since v2.0.0

Zips this chunk pointwise with the specified chunk using the specified combiner.

Signature

declare const zipWith: {
<A, B, C>(that: Chunk<B>, f: (a: A, b: B) => C): (self: Chunk<A>) => Chunk<C>;
<A, B, C>(self: Chunk<A>, that: Chunk<B>, f: (a: A, b: B) => C): Chunk<C>;
}

Example Zipping chunks with a function

import { Chunk } from "effect"
const numbers = Chunk.make(1, 2, 3)
const letters = Chunk.make("a", "b", "c")
Chunk.toArray(Chunk.zipWith(numbers, letters, (n, l) => `${n}-${l}`)) // => ["1-a", "2-b", "3-c"]
// Different lengths - takes minimum
const short = Chunk.make(1, 2)
const long = Chunk.make("a", "b", "c", "d")
Chunk.toArray(Chunk.zipWith(short, long, (n, l) => [n, l])) // => [[1, "a"], [2, "b"]]