Skip to content

NonEmptyIterable.ts

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

  • NonEmptyIterable for the branded iterable type that uses this symbol

Since v2.0.0



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.from
const 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) // 1
console.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 generators
function* 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) // 1
console.log(globalThis.Array.from(iteratorToIterable(restFib))) // [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
// Practical usage: implementing reduce for non-empty iterables
function 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) // 10

Signature

declare const unprepend: <A>(self: NonEmptyIterable<A>) => [firstElement: A, remainingElements: Iterator<A>]

Source

Since v2.0.0

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 data
function 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 iterable
const 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 generator
function* countdown(): Generator<number> {
yield 3
yield 2
yield 1
}
const firstCount = getFirst(Chunk.fromIterable(countdown()) as unknown as NonEmptyIterable.NonEmptyIterable<number>) // 3

Signature

export interface NonEmptyIterable<out A> extends Iterable<A> {
readonly [nonEmpty]: A
}

Source

Since v2.0.0