Chunk
Chunk<A> is an immutable, ordered sequence of values. It behaves like a
read-only array — you can map, filter, take, and index into it — but every
operation returns a new Chunk rather than mutating the original, and it
compares by value (Equal.equals) rather than by reference. Chunks are the
backing collection for Streaming: a stream delivers its elements
in chunks, so you will see Chunk whenever you pull data out of a Stream.
import { Chunk } from "effect"
// Build a chunk and transform it — each step yields a fresh, immutable Chunkconst evensDoubled = Chunk.make(1, 2, 3, 4, 5, 6).pipe( Chunk.filter((n) => n % 2 === 0), Chunk.map((n) => n * 2))
// Convert back to a plain array at the boundary of your codeconsole.log(Chunk.toReadonlyArray(evensDoubled)) // [4, 8, 12]Each pipe step produces a new Chunk; the original make(1, …, 6) is never
changed. When you need a normal array (to return from an API, say), convert with
Chunk.toReadonlyArray.
Creating a Chunk
Section titled “Creating a Chunk”import { Chunk } from "effect"
const empty = Chunk.empty<number>()const explicit = Chunk.make(1, 2, 3) // from valuesconst fromArray = Chunk.fromIterable([1, 2, 3]) // from any Iterableconst single = Chunk.of(1) // one elementAdding and combining
Section titled “Adding and combining”append / prepend add a single element; appendAll concatenates two chunks.
All of them return a new chunk.
import { Chunk } from "effect"
const base = Chunk.make(2, 3)
console.log(Chunk.toReadonlyArray(Chunk.prepend(base, 1))) // [1, 2, 3]console.log(Chunk.toReadonlyArray(Chunk.append(base, 4))) // [2, 3, 4]console.log( Chunk.toReadonlyArray(Chunk.appendAll(base, Chunk.make(4, 5)))) // [2, 3, 4, 5]Reading elements
Section titled “Reading elements”Chunk.get returns an Option for safe indexing; Chunk.head and Chunk.last
are also Option-returning because a chunk may be empty. Chunk.size reports
the length.
import { Chunk } from "effect"
const chunk = Chunk.make(10, 20, 30)
console.log(Chunk.size(chunk)) // 3console.log(Chunk.get(chunk, 1)) // { _id: 'Option', _tag: 'Some', value: 20 }console.log(Chunk.get(chunk, 5)) // { _id: 'Option', _tag: 'None' }console.log(Chunk.head(chunk)) // { _id: 'Option', _tag: 'Some', value: 10 }Because out-of-bounds access yields None rather than undefined, you cannot
forget to handle the empty/missing case.
Slicing and folding
Section titled “Slicing and folding”The familiar collection operations are all here and all immutable:
import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3, 4, 5)
console.log(Chunk.toReadonlyArray(Chunk.take(chunk, 2))) // [1, 2]console.log(Chunk.toReadonlyArray(Chunk.drop(chunk, 2))) // [3, 4, 5]console.log(Chunk.toReadonlyArray(Chunk.reverse(chunk))) // [5, 4, 3, 2, 1]console.log(Chunk.reduce(chunk, 0, (sum, n) => sum + n)) // 15Value equality
Section titled “Value equality”Two chunks built separately are equal when their elements are equal, so a
Chunk is safe to compare in tests and to use as a value inside other
structurally-compared types.
import { Chunk, Equal } from "effect"
console.log(Equal.equals(Chunk.make(1, 2, 3), Chunk.make(1, 2, 3))) // trueconsole.log(Equal.equals(Chunk.make(1, 2), Chunk.make(1, 2, 3))) // falseWhen to use Chunk
Section titled “When to use Chunk”For everyday in-memory lists, a plain ReadonlyArray and the Array module are
perfectly fine. Reach for Chunk when you are working with
Streaming (where it is the native element container), or when you
want guaranteed immutability and structural equality for a sequence. Convert
with Chunk.fromIterable going in and Chunk.toReadonlyArray coming out.