<A>(self: NonEmptyIterable<A>): [
firstElement: A,
remainingElements: Iterator<A>
]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) // 10export const const unprepend: <A>(
self: NonEmptyIterable<A>
) => [
firstElement: A,
remainingElements: Iterator<A>
]
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
unprepend = <function (type parameter) A in <A>(self: NonEmptyIterable<A>): [firstElement: A, remainingElements: Iterator<A>]A>(self: NonEmptyIterable<A>self: interface NonEmptyIterable<out A>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
NonEmptyIterable<function (type parameter) A in <A>(self: NonEmptyIterable<A>): [firstElement: A, remainingElements: Iterator<A>]A>): [AfirstElement: function (type parameter) A in <A>(self: NonEmptyIterable<A>): [firstElement: A, remainingElements: Iterator<A>]A, Iterator<A, any, any>remainingElements: interface Iterator<T, TReturn = any, TNext = any>Iterator<function (type parameter) A in <A>(self: NonEmptyIterable<A>): [firstElement: A, remainingElements: Iterator<A>]A>] => {
const const iterator: Iterator<A, any, any>iterator = self: NonEmptyIterable<A>self[var Symbol: SymbolConstructorSymbol.SymbolConstructor.iterator: typeof Symbol.iteratorA method that returns the default iterator for an object. Called by the semantics of the
for-of statement.
iterator]()
const const next: IteratorResult<A, any>next = const iterator: Iterator<A, any, any>iterator.Iterator<A, any, any>.next(...[value]: [] | [any]): IteratorResult<A, any>next()
if (const next: IteratorResult<A, any>next.done?: boolean | undefineddone) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
"BUG: NonEmptyIterator should not be empty - please report an issue at https://github.com/Effect-TS/effect/issues"
)
}
return [const next: IteratorYieldResult<A>next.IteratorYieldResult<A>.value: Avalue, const iterator: Iterator<A, any, any>iterator]
}