NonEmptyIterable.ts
NonEmptyIterable.ts overview
Section titled “NonEmptyIterable.ts overview”Defines the type-level symbol used to brand the NonEmptyIterable type.
When to use
Use as the property key for the type-level brand that marks an Iterable as
non-empty.
Details
NonEmptyIterable<A> includes readonly [nonEmpty]: A, which makes it
distinct from a plain Iterable<A> at compile time while preserving the
normal iteration shape.
See
NonEmptyIterablefor the branded iterable type that uses this symbol
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”getters
Section titled “getters”unprepend
Section titled “unprepend”Extracts the first element and remaining elements from a non-empty iterable safely.
When to use
Use to split a non-empty iterable into its first element and an iterator for the remaining elements.
Details
This function provides a safe way to deconstruct a NonEmptyIterable into its
head (first element) and tail (remaining elements as an iterator). Since the
iterable is guaranteed to be non-empty, the first element is always available.
Example (Extracting first and remaining elements)
import { Array, Chunk, NonEmptyIterable } from "effect"
// Helper to make iterator iterable for Array.fromconst iteratorToIterable = <T>(iterator: Iterator<T>): Iterable<T> => ({ [Symbol.iterator]() { return iterator }})
// With NonEmptyArray from Array.make (cast to NonEmptyIterable)const numbers = Array.make(1, 2, 3, 4, 5) as unknown as NonEmptyIterable.NonEmptyIterable<number>const [first, rest] = NonEmptyIterable.unprepend(numbers)console.log(first) // 1console.log(globalThis.Array.from(iteratorToIterable(rest))) // [2, 3, 4, 5]
// With strings (assert when known to be non-empty)const text = "hello" as unknown as NonEmptyIterable.NonEmptyIterable<string>const [firstChar, restChars] = NonEmptyIterable.unprepend(text)console.log(firstChar) // "h"console.log(globalThis.Array.from(iteratorToIterable(restChars)).join("")) // "ello"
// With Sets (assert when known to be non-empty)const uniqueNumbers = new Set([10, 20, 30]) as unknown as NonEmptyIterable.NonEmptyIterable<number>const [firstUnique, restUnique] = NonEmptyIterable.unprepend(uniqueNumbers)console.log(firstUnique) // 10 (or any element, Set order is not guaranteed)console.log(globalThis.Array.from(iteratorToIterable(restUnique))) // [20, 30] (in some order)
// With Maps (assert when known to be non-empty)const keyValuePairs = new Map([ ["a", 1], ["b", 2], ["c", 3]]) as unknown as NonEmptyIterable.NonEmptyIterable<[string, number]>const [firstPair, restPairs] = NonEmptyIterable.unprepend(keyValuePairs)console.log(firstPair) // ["a", 1]console.log(globalThis.Array.from(iteratorToIterable(restPairs))) // [["b", 2], ["c", 3]]
// With custom generatorsfunction* fibonacci(): Generator<number> { let a = 1, b = 1 yield a for (let i = 0; i < 10; i++) { yield b const next = a + b a = b b = next }}
const generator = Chunk.fromIterable(fibonacci()) as unknown as NonEmptyIterable.NonEmptyIterable<number>const [firstFib, restFib] = NonEmptyIterable.unprepend(generator)console.log(firstFib) // 1console.log(globalThis.Array.from(iteratorToIterable(restFib))) // [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
// Practical usage: implementing reduce for non-empty iterablesfunction reduceNonEmpty<A, B>(data: NonEmptyIterable.NonEmptyIterable<A>, f: (acc: B, current: A) => B, initial: B): B { const [first, rest] = NonEmptyIterable.unprepend(data) let result = f(initial, first)
// Convert iterator to iterable for iteration const iterable = { [Symbol.iterator]() { return rest } } for (const item of iterable) { result = f(result, item) }
return result}
const data = Array.make(1, 2, 3, 4) as unknown as NonEmptyIterable.NonEmptyIterable<number>const sum = reduceNonEmpty(data, (acc, x) => acc + x, 0) // 10Signature
declare const unprepend: <A>(self: NonEmptyIterable<A>) => [firstElement: A, remainingElements: Iterator<A>]Since v2.0.0
models
Section titled “models”NonEmptyIterable (interface)
Section titled “NonEmptyIterable (interface)”Represents an iterable that is guaranteed to contain at least one element.
When to use
Use to require an iterable input that must provide at least one element.
Details
NonEmptyIterable<A> extends the standard Iterable<A> interface with a type-level
guarantee of non-emptiness. This allows for safe operations that would otherwise
require runtime checks or could throw exceptions.
The type is branded with a unique symbol to ensure type safety while maintaining full compatibility with JavaScript’s iteration protocol.
Example (Working with non-empty iterables)
import { Array, Chunk, NonEmptyIterable } from "effect"
// Function that requires non-empty datafunction getFirst<A>(data: NonEmptyIterable.NonEmptyIterable<A>): A { // Safe - guaranteed to have at least one element const [first] = NonEmptyIterable.unprepend(data) return first}
// Works with any non-empty iterableconst numbers = Array.make(1, 2, 3) as unknown as NonEmptyIterable.NonEmptyIterable<number>const firstNumber = getFirst(numbers) // 1
const chars = "hello" as unknown as NonEmptyIterable.NonEmptyIterable<string>const firstChar = getFirst(chars) // "h"
const entries = new Map([ ["a", 1], ["b", 2]]) as unknown as NonEmptyIterable.NonEmptyIterable<[string, number]>const firstEntry = getFirst(entries) // ["a", 1]
// Custom generatorfunction* countdown(): Generator<number> { yield 3 yield 2 yield 1}const firstCount = getFirst(Chunk.fromIterable(countdown()) as unknown as NonEmptyIterable.NonEmptyIterable<number>) // 3Signature
export interface NonEmptyIterable<out A> extends Iterable<A> { readonly [nonEmpty]: A}Since v2.0.0