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.
Why Chunk over Array?
Section titled “Why Chunk over Array?”A Chunk gives you two things a plain array does not:
- Value equality via
Equal. Arrays compare by reference ([1,2] !== [1,2]), whileEqual.equals(Chunk.make(1, 2), Chunk.make(1, 2))istrue. This makes chunks safe keys/values insideHashMap,HashSet, and other structurally-compared types, and removes a class of test flakiness. - Fast concatenation, append, and prepend. Internally a
Chunkis a balanced tree of array segments, soappendAll,append, andprependare cheap and share structure rather than copying. This is exactly whyStreamaccumulates and hands you data as chunks: building up output by concatenation is the hot path in streaming.
When you only need an in-memory list and don’t care about either property, the
Array module on plain ReadonlyArray is lighter weight.
NonEmptyChunk
Section titled “NonEmptyChunk”NonEmptyChunk<A> is a Chunk<A> that the type system knows has at least one
element. Constructors like make, of, makeBy, and range return one, and
the isNonEmpty refinement narrows a Chunk to a NonEmptyChunk so that
“head” and “last” become total (non-Option) operations.
import { Chunk } from "effect"
const chunk: Chunk.Chunk<number> = Chunk.make(1, 2, 3)
if (Chunk.isNonEmpty(chunk)) { // inside this branch `chunk` is a NonEmptyChunk console.log(Chunk.headNonEmpty(chunk)) // 1 (a plain number, not Option) console.log(Chunk.lastNonEmpty(chunk)) // 3}Operations that preserve non-emptiness do so in their types: map, reverse,
append, prepend, and appendAll/prependAll (when one side is non-empty)
all return NonEmptyChunk from a NonEmptyChunk input.
Reference
Section titled “Reference”Every public Chunk export, grouped by purpose. All examples assume
import { Chunk } from "effect" (plus any extra modules shown). Many operations
return a new Chunk; we materialize results with Chunk.toReadonlyArray (// =>)
where the printed form matters.
Types & guards
Section titled “Types & guards”The core immutable sequence type, Chunk<A>. It is Iterable, Equal,
Pipeable, and Inspectable, and exposes a .length.
const chunk: Chunk.Chunk<number> = Chunk.make(1, 2, 3)console.log(chunk.length) // => 3NonEmptyChunk
Section titled “NonEmptyChunk”A Chunk<A> proven to hold at least one element; enables total head/last access.
const ne: Chunk.NonEmptyChunk<number> = Chunk.make(1, 2, 3)console.log(Chunk.headNonEmpty(ne)) // => 1ChunkTypeLambda
Section titled “ChunkTypeLambda”The higher-kinded type lambda for Chunk, used when writing generic abstractions
over type constructors (HKT).
import type { Chunk, HKT } from "effect"
type NumberChunk = HKT.Kind<Chunk.ChunkTypeLambda, never, never, never, number>// => Chunk<number>isChunk
Section titled “isChunk”Type guard: checks whether an unknown value is a Chunk.
console.log(Chunk.isChunk(Chunk.make(1, 2, 3))) // => trueconsole.log(Chunk.isChunk([1, 2, 3])) // => falseisEmpty
Section titled “isEmpty”Returns true when the chunk has no elements.
console.log(Chunk.isEmpty(Chunk.empty())) // => trueconsole.log(Chunk.isEmpty(Chunk.make(1))) // => falseisNonEmpty
Section titled “isNonEmpty”Refinement: returns true when the chunk has at least one element and narrows it
to NonEmptyChunk.
const chunk = Chunk.make(1, 2)if (Chunk.isNonEmpty(chunk)) { console.log(Chunk.headNonEmpty(chunk)) // => 1}makeEquivalence
Section titled “makeEquivalence”Builds an Equivalence for chunks from an element-level Equivalence (compares
length, then elements pairwise).
import { Chunk, Equivalence } from "effect"
const eq = Chunk.makeEquivalence(Equivalence.strictEqual<number>())console.log(eq(Chunk.make(1, 2, 3), Chunk.make(1, 2, 3))) // => trueconsole.log(eq(Chunk.make(1, 2, 3), Chunk.make(1, 2, 4))) // => falseConstructors
Section titled “Constructors”Creates an empty chunk.
console.log(Chunk.size(Chunk.empty<number>())) // => 0Builds a NonEmptyChunk from one or more inline values.
console.log(Chunk.toReadonlyArray(Chunk.make(1, 2, 3))) // => [1, 2, 3]Builds a single-element NonEmptyChunk.
console.log(Chunk.toReadonlyArray(Chunk.of("hello"))) // => ["hello"]fromIterable
Section titled “fromIterable”Creates a chunk from any iterable (arrays, sets, generators, …). Returns the
input unchanged if it is already a Chunk.
console.log(Chunk.toReadonlyArray(Chunk.fromIterable(new Set([1, 2, 2, 3])))) // => [1, 2, 3]fromArrayUnsafe
Section titled “fromArrayUnsafe”Wraps an array into a chunk without copying — mutating the source array later mutates the chunk. Use only when you own the array and won’t mutate it.
const arr = [1, 2, 3]const chunk = Chunk.fromArrayUnsafe(arr)arr[0] = 999console.log(Chunk.toReadonlyArray(chunk)) // => [999, 2, 3]fromNonEmptyArrayUnsafe
Section titled “fromNonEmptyArrayUnsafe”Like fromArrayUnsafe, but for a non-empty array; returns a NonEmptyChunk
without copying.
import { Array, Chunk } from "effect"
const chunk = Chunk.fromNonEmptyArrayUnsafe(Array.make(1, 2, 3))console.log(Chunk.isNonEmpty(chunk)) // => truemakeBy
Section titled “makeBy”Builds a NonEmptyChunk of length n, initializing each element from its index.
console.log(Chunk.toReadonlyArray(Chunk.makeBy(5, (i) => i * 2))) // => [0, 2, 4, 6, 8]Creates a NonEmptyChunk of consecutive integers from start to end
inclusive. If start > end it returns a single-element chunk of start.
console.log(Chunk.toReadonlyArray(Chunk.range(1, 5))) // => [1, 2, 3, 4, 5]Conversions
Section titled “Conversions”toArray
Section titled “toArray”Converts a chunk to a fresh, mutable Array. A NonEmptyChunk yields a
NonEmptyArray.
const arr = Chunk.toArray(Chunk.make(1, 2, 3))console.log(arr) // => [1, 2, 3]console.log(Array.isArray(arr)) // => truetoReadonlyArray
Section titled “toReadonlyArray”Converts a chunk to a ReadonlyArray (the canonical way to leave Chunk-land). A
NonEmptyChunk yields a NonEmptyReadonlyArray.
console.log(Chunk.toReadonlyArray(Chunk.make(1, 2, 3))) // => [1, 2, 3]Access
Section titled “Access”Safely reads the element at an index, returning Option. Out-of-bounds yields
None.
import { Chunk, Option } from "effect"
const chunk = Chunk.make("a", "b", "c")console.log(Chunk.get(chunk, 1)) // => Option.some("b")console.log(Chunk.get(chunk, 10)) // => Option.none()getUnsafe
Section titled “getUnsafe”Reads the element at an index, throwing on out-of-bounds. Prefer get when the
index might be invalid.
console.log(Chunk.getUnsafe(Chunk.make("a", "b", "c"), 2)) // => "c"Returns the first element as an Option.
console.log(Chunk.head(Chunk.make(1, 2, 3))) // => Option.some(1)console.log(Chunk.head(Chunk.empty())) // => Option.none()headUnsafe
Section titled “headUnsafe”Returns the first element, throwing if the chunk is empty.
console.log(Chunk.headUnsafe(Chunk.make(1, 2, 3))) // => 1headNonEmpty
Section titled “headNonEmpty”Total first-element access for a NonEmptyChunk (no Option, never throws).
console.log(Chunk.headNonEmpty(Chunk.make(1, 2, 3))) // => 1Returns the last element as an Option.
console.log(Chunk.last(Chunk.make(1, 2, 3))) // => Option.some(3)console.log(Chunk.last(Chunk.empty())) // => Option.none()lastUnsafe
Section titled “lastUnsafe”Returns the last element, throwing if the chunk is empty.
console.log(Chunk.lastUnsafe(Chunk.make(1, 2, 3))) // => 3lastNonEmpty
Section titled “lastNonEmpty”Total last-element access for a NonEmptyChunk.
console.log(Chunk.lastNonEmpty(Chunk.make(1, 2, 3))) // => 3Returns every element after the first, wrapped in Option (None if empty).
import { Chunk, Option } from "effect"
const t = Chunk.tail(Chunk.make(1, 2, 3))console.log(Option.map(t, Chunk.toReadonlyArray)) // => Option.some([2, 3])console.log(Chunk.tail(Chunk.empty())) // => Option.none()tailNonEmpty
Section titled “tailNonEmpty”Returns every element after the first from a NonEmptyChunk (total; may be
empty).
console.log(Chunk.toReadonlyArray(Chunk.tailNonEmpty(Chunk.make(1, 2, 3)))) // => [2, 3]Returns the number of elements.
console.log(Chunk.size(Chunk.make(1, 2, 3))) // => 3Concatenation
Section titled “Concatenation”append
Section titled “append”Adds one element to the end, returning a NonEmptyChunk.
console.log(Chunk.toReadonlyArray(Chunk.append(Chunk.make(1, 2), 3))) // => [1, 2, 3]prepend
Section titled “prepend”Adds one element to the front, returning a NonEmptyChunk.
console.log(Chunk.toReadonlyArray(Chunk.prepend(Chunk.make(2, 3), 1))) // => [1, 2, 3]appendAll
Section titled “appendAll”Concatenates two chunks (self first). Non-emptiness of either input is
preserved in the type.
console.log( Chunk.toReadonlyArray(Chunk.appendAll(Chunk.make(1, 2), Chunk.make(3, 4)))) // => [1, 2, 3, 4]prependAll
Section titled “prependAll”Concatenates that before self (the prefix comes first).
console.log( Chunk.make(1, 2).pipe(Chunk.prependAll(Chunk.make("a", "b")), Chunk.toReadonlyArray)) // => ["a", "b", 1, 2]Slicing
Section titled “Slicing”Keeps the first n elements.
console.log(Chunk.toReadonlyArray(Chunk.take(Chunk.make(1, 2, 3, 4, 5), 3))) // => [1, 2, 3]takeRight
Section titled “takeRight”Keeps the last n elements.
console.log(Chunk.toReadonlyArray(Chunk.takeRight(Chunk.make(1, 2, 3, 4, 5), 2))) // => [4, 5]takeWhile
Section titled “takeWhile”Keeps the leading run of elements that satisfy a predicate. Accepts a refinement to narrow the element type.
console.log( Chunk.toReadonlyArray(Chunk.takeWhile(Chunk.make(1, 2, 3, 4, 1), (n) => n < 3))) // => [1, 2]Discards the first n elements.
console.log(Chunk.toReadonlyArray(Chunk.drop(Chunk.make(1, 2, 3, 4, 5), 2))) // => [3, 4, 5]dropRight
Section titled “dropRight”Discards the last n elements.
console.log(Chunk.toReadonlyArray(Chunk.dropRight(Chunk.make(1, 2, 3, 4, 5), 2))) // => [1, 2, 3]dropWhile
Section titled “dropWhile”Discards the leading run of elements that satisfy a predicate.
console.log( Chunk.toReadonlyArray(Chunk.dropWhile(Chunk.make(1, 2, 3, 4, 5), (n) => n < 3))) // => [3, 4, 5]splitAt
Section titled “splitAt”Splits into [before, from] at an index.
const [before, after] = Chunk.splitAt(Chunk.make(1, 2, 3, 4), 2)console.log(Chunk.toReadonlyArray(before)) // => [1, 2]console.log(Chunk.toReadonlyArray(after)) // => [3, 4]splitNonEmptyAt
Section titled “splitNonEmptyAt”Splits a NonEmptyChunk at n, returning a non-empty prefix and a possibly-empty
suffix (n is clamped to at least 1).
const [first, rest] = Chunk.splitNonEmptyAt(Chunk.make(1, 2, 3, 4), 1)console.log(Chunk.toReadonlyArray(first)) // => [1]console.log(Chunk.toReadonlyArray(rest)) // => [2, 3, 4]Splits into up to n roughly-equal chunks, distributing elements in order.
console.log( Chunk.toReadonlyArray(Chunk.split(Chunk.make(1, 2, 3, 4, 5), 2)).map(Chunk.toReadonlyArray)) // => [[1, 2, 3], [4, 5]]splitWhere
Section titled “splitWhere”Splits on the first element matching a predicate into [before, fromMatch].
const [before, fromMatch] = Chunk.splitWhere(Chunk.make(1, 2, 3, 4), (n) => n > 2)console.log(Chunk.toReadonlyArray(before)) // => [1, 2]console.log(Chunk.toReadonlyArray(fromMatch)) // => [3, 4]chunksOf
Section titled “chunksOf”Groups elements into sub-chunks of up to n elements each.
console.log( Chunk.toReadonlyArray(Chunk.chunksOf(Chunk.make(1, 2, 3, 4, 5), 2)).map(Chunk.toReadonlyArray)) // => [[1, 2], [3, 4], [5]]Searching
Section titled “Searching”contains
Section titled “contains”Checks membership using the default Equal equivalence.
console.log(Chunk.contains(Chunk.make(1, 2, 3), 2)) // => trueconsole.log(Chunk.contains(Chunk.make(1, 2, 3), 9)) // => falsecontainsWith
Section titled “containsWith”Checks membership using a custom equivalence function.
const ci = Chunk.containsWith<string>((a, b) => a.toLowerCase() === b.toLowerCase())console.log(ci(Chunk.make("Apple", "Banana"), "apple")) // => truefindFirst
Section titled “findFirst”Returns the first element matching a predicate (or refinement) as an Option.
console.log(Chunk.findFirst(Chunk.make(1, 2, 3, 4), (n) => n > 2)) // => Option.some(3)findFirstIndex
Section titled “findFirstIndex”Returns the index of the first matching element as an Option.
console.log(Chunk.findFirstIndex(Chunk.make(1, 2, 3, 4), (n) => n > 2)) // => Option.some(2)findLast
Section titled “findLast”Returns the last element matching a predicate (or refinement) as an Option.
console.log(Chunk.findLast(Chunk.make(1, 2, 3, 4), (n) => n < 4)) // => Option.some(3)findLastIndex
Section titled “findLastIndex”Returns the index of the last matching element as an Option.
console.log(Chunk.findLastIndex(Chunk.make(1, 2, 3, 4), (n) => n < 4)) // => Option.some(2)Returns true if every element satisfies the predicate; with a refinement it
narrows the chunk’s element type.
console.log(Chunk.every(Chunk.make(2, 4, 6), (n) => n % 2 === 0)) // => trueReturns true if at least one element satisfies the predicate; narrows the chunk
to NonEmptyChunk on success.
console.log(Chunk.some(Chunk.make(1, 2, 3), (n) => n > 2)) // => trueModifying
Section titled “Modifying”remove
Section titled “remove”Deletes the element at an index. Out-of-bounds indices leave the chunk unchanged.
console.log(Chunk.toReadonlyArray(Chunk.remove(Chunk.make("a", "b", "c"), 1))) // => ["a", "c"]modify
Section titled “modify”Applies a function to the element at an index, returning Option<Chunk> (None
if out of bounds).
import { Chunk, Option } from "effect"
const result = Chunk.modify(Chunk.make(1, 2, 3), 1, (n) => n * 10)console.log(Option.map(result, Chunk.toReadonlyArray)) // => Option.some([1, 20, 3])replace
Section titled “replace”Replaces the element at an index with a value, returning Option<Chunk> (None
if out of bounds).
import { Chunk, Option } from "effect"
const result = Chunk.replace(Chunk.make("a", "b", "c"), 1, "X")console.log(Option.map(result, Chunk.toReadonlyArray)) // => Option.some(["a", "X", "c"])reverse
Section titled “reverse”Reverses the order of elements. A NonEmptyChunk stays non-empty.
console.log(Chunk.toReadonlyArray(Chunk.reverse(Chunk.make(1, 2, 3)))) // => [3, 2, 1]Mapping & folding
Section titled “Mapping & folding”Transforms every element. The mapper receives (element, index); non-emptiness
is preserved.
console.log(Chunk.toReadonlyArray(Chunk.map(Chunk.make(1, 2, 3), (n) => n + 1))) // => [2, 3, 4]mapAccum
Section titled “mapAccum”Maps statefully, threading an accumulator and returning [finalState, chunk].
const [total, running] = Chunk.mapAccum(Chunk.make(1, 2, 3), 0, (acc, n) => [acc + n, acc + n])console.log(total) // => 6console.log(Chunk.toReadonlyArray(running)) // => [1, 3, 6]flatMap
Section titled “flatMap”Maps each element to a chunk and concatenates the results. The mapper receives
(element, index).
console.log( Chunk.toReadonlyArray(Chunk.flatMap(Chunk.make(1, 2, 3), (n) => Chunk.make(n, n)))) // => [1, 1, 2, 2, 3, 3]flatten
Section titled “flatten”Flattens a chunk of chunks into a single chunk.
console.log( Chunk.toReadonlyArray(Chunk.flatten(Chunk.make(Chunk.make(1, 2), Chunk.make(3, 4))))) // => [1, 2, 3, 4]forEach
Section titled “forEach”Runs a side-effecting function over each element; returns void.
Chunk.forEach(Chunk.make(1, 2, 3), (n) => console.log(n))// logs 1, 2, 3filter
Section titled “filter”Keeps elements satisfying a predicate; with a refinement it narrows the element type.
console.log( Chunk.toReadonlyArray(Chunk.filter(Chunk.make(1, 2, 3, 4), (n) => n % 2 === 0))) // => [2, 4]filterMap
Section titled “filterMap”Maps and filters in one pass: the mapper returns a Result, and only success
values are kept. The mapper receives (element, index).
import { Chunk, Result } from "effect"
const nums = Chunk.filterMap(Chunk.make("1", "x", "3"), (s) => { const n = parseInt(s) return isNaN(n) ? Result.failVoid : Result.succeed(n)})console.log(Chunk.toReadonlyArray(nums)) // => [1, 3]filterMapWhile
Section titled “filterMapWhile”Like filterMap, but stops at the first element the Filter rejects.
import { Chunk, Result } from "effect"
const result = Chunk.filterMapWhile(Chunk.make("1", "2", "x", "3"), (s) => { const n = parseInt(s) return isNaN(n) ? Result.failVoid : Result.succeed(n)})console.log(Chunk.toReadonlyArray(result)) // => [1, 2] (stops at "x")compact
Section titled “compact”Drops Nones from a Chunk<Option<A>>, keeping the unwrapped Some values.
import { Chunk, Option } from "effect"
console.log( Chunk.toReadonlyArray(Chunk.compact(Chunk.make(Option.some(1), Option.none(), Option.some(3))))) // => [1, 3]partition
Section titled “partition”Splits a chunk with a Result-returning function into [excluded, satisfying];
the mapper receives (element, index).
import { Chunk, Result } from "effect"
const [excluded, satisfying] = Chunk.partition(Chunk.make(1, -2, 3), (n) => n > 0 ? Result.succeed(n) : Result.fail(`neg:${n}`))console.log(Chunk.toReadonlyArray(excluded)) // => ["neg:-2"]console.log(Chunk.toReadonlyArray(satisfying)) // => [1, 3]separate
Section titled “separate”Splits a Chunk<Result<B, A>> into [failures, successes].
import { Chunk, Result } from "effect"
const [errors, values] = Chunk.separate( Chunk.make(Result.succeed(1), Result.fail("e"), Result.succeed(2)))console.log(Chunk.toReadonlyArray(errors)) // => ["e"]console.log(Chunk.toReadonlyArray(values)) // => [1, 2]reduce
Section titled “reduce”Folds the elements left-to-right with an accumulator; the reducer receives
(acc, element, index).
console.log(Chunk.reduce(Chunk.make(1, 2, 3, 4), 0, (acc, n) => acc + n)) // => 10reduceRight
Section titled “reduceRight”Folds the elements right-to-left.
console.log(Chunk.reduceRight(Chunk.make(1, 2, 3, 4), 0, (acc, n) => acc + n)) // => 10Joins a Chunk<string> into a single string with a separator.
console.log(Chunk.join(Chunk.make("a", "b", "c"), ", ")) // => "a, b, c"Sorting
Section titled “Sorting”Sorts elements with an Order, returning a new chunk.
import { Chunk, Order } from "effect"
console.log(Chunk.toReadonlyArray(Chunk.sort(Chunk.make(3, 1, 2), Order.Number))) // => [1, 2, 3]sortWith
Section titled “sortWith”Sorts by a value derived from each element via a projection plus an Order.
import { Chunk, Order } from "effect"
const people = Chunk.make({ name: "Bob", age: 25 }, { name: "Alice", age: 30 })const byAge = Chunk.sortWith(people, (p) => p.age, Order.Number)console.log(Chunk.toReadonlyArray(byAge).map((p) => p.name)) // => ["Bob", "Alice"]Set operations, zipping & dedupe
Section titled “Set operations, zipping & dedupe”Concatenates two chunks and removes duplicates, preserving order of first appearance.
console.log( Chunk.toReadonlyArray(Chunk.union(Chunk.make(1, 2, 3), Chunk.make(3, 4, 5)))) // => [1, 2, 3, 4, 5]intersection
Section titled “intersection”Keeps values present in both chunks; order and references come from the first.
console.log( Chunk.toReadonlyArray(Chunk.intersection(Chunk.make(1, 2, 3, 4), Chunk.make(3, 4, 5)))) // => [3, 4]difference
Section titled “difference”Keeps values from self that are not in that.
console.log( Chunk.toReadonlyArray(Chunk.difference(Chunk.make(1, 2, 3, 4, 5), Chunk.make(3, 4, 6)))) // => [1, 2, 5]differenceWith
Section titled “differenceWith”Like difference, but using a custom equivalence function.
const byId = Chunk.differenceWith<{ id: number }>((a, b) => a.id === b.id)const result = byId(Chunk.make({ id: 1 }, { id: 2 }), Chunk.make({ id: 1 }))console.log(Chunk.toReadonlyArray(result)) // => [{ id: 2 }]Pairs elements pointwise into tuples, stopping at the shorter chunk.
console.log( Chunk.toReadonlyArray(Chunk.zip(Chunk.make(1, 2, 3), Chunk.make("a", "b", "c")))) // => [[1, "a"], [2, "b"], [3, "c"]]zipWith
Section titled “zipWith”Combines elements pointwise with a function, stopping at the shorter chunk.
console.log( Chunk.toReadonlyArray( Chunk.zipWith(Chunk.make(1, 2, 3), Chunk.make("a", "b", "c"), (n, l) => `${n}-${l}`) )) // => ["1-a", "2-b", "3-c"]The inverse of zip: splits a chunk of pairs into a pair of chunks.
const [nums, letters] = Chunk.unzip(Chunk.make([1, "a"] as const, [2, "b"] as const))console.log(Chunk.toReadonlyArray(nums)) // => [1, 2]console.log(Chunk.toReadonlyArray(letters)) // => ["a", "b"]dedupe
Section titled “dedupe”Removes duplicate values, keeping the first occurrence of each.
console.log(Chunk.toReadonlyArray(Chunk.dedupe(Chunk.make(1, 2, 2, 3, 1)))) // => [1, 2, 3]dedupeAdjacent
Section titled “dedupeAdjacent”Removes only consecutive duplicate values, leaving non-adjacent repeats intact.
console.log( Chunk.toReadonlyArray(Chunk.dedupeAdjacent(Chunk.make(1, 1, 2, 2, 3, 1, 1)))) // => [1, 2, 3, 1]