<B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>Generates an iterable by repeatedly applying a function that produces the next element and state.
Details
This is useful for creating iterables from a generating function that
maintains state. The function should return Option.some([value, nextState])
to continue or Option.none() to stop.
Example (Unfolding state into values)
import { Iterable, Option } from "effect"
// Generate Fibonacci sequence
const fibonacci = Iterable.unfold([0, 1], ([a, b]) => Option.some([a, [b, a + b]]))
const first10Fib = Iterable.take(fibonacci, 10)
console.log(Array.from(first10Fib)) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
// Generate powers of 2 up to a limit
const powersOf2 = Iterable.unfold(1, (n) => n <= 1000 ? Option.some([n, n * 2]) : Option.none())
console.log(Array.from(powersOf2)) // [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
// Generate countdown
const countdown = Iterable.unfold(5, (n) => n > 0 ? Option.some([n, n - 1]) : Option.none())
console.log(Array.from(countdown)) // [5, 4, 3, 2, 1]
// Generate collatz sequence
const collatz = Iterable.unfold(7, (n) => {
if (n === 1) return Option.none()
const next = n % 2 === 0 ? n / 2 : n * 3 + 1
return Option.some([n, next])
})
console.log(Array.from(collatz)) // [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2]export const const unfold: <B, A>(
b: B,
f: (b: B) => Option<readonly [A, B]>
) => Iterable<A>
Generates an iterable by repeatedly applying a function that produces the
next element and state.
Details
This is useful for creating iterables from a generating function that
maintains state. The function should return Option.some([value, nextState])
to continue or Option.none() to stop.
Example (Unfolding state into values)
import { Iterable, Option } from "effect"
// Generate Fibonacci sequence
const fibonacci = Iterable.unfold([0, 1], ([a, b]) => Option.some([a, [b, a + b]]))
const first10Fib = Iterable.take(fibonacci, 10)
console.log(Array.from(first10Fib)) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
// Generate powers of 2 up to a limit
const powersOf2 = Iterable.unfold(1, (n) => n <= 1000 ? Option.some([n, n * 2]) : Option.none())
console.log(Array.from(powersOf2)) // [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
// Generate countdown
const countdown = Iterable.unfold(5, (n) => n > 0 ? Option.some([n, n - 1]) : Option.none())
console.log(Array.from(countdown)) // [5, 4, 3, 2, 1]
// Generate collatz sequence
const collatz = Iterable.unfold(7, (n) => {
if (n === 1) return Option.none()
const next = n % 2 === 0 ? n / 2 : n * 3 + 1
return Option.some([n, next])
})
console.log(Array.from(collatz)) // [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2]
unfold = <function (type parameter) B in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>B, function (type parameter) A in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>A>(b: Bb: function (type parameter) B in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>B, f: (b: B) => Option<readonly [A, B]>f: (b: Bb: function (type parameter) B in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>B) => type Option<A> = O.None<A> | O.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<readonly [function (type parameter) A in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>A, function (type parameter) B in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>B]>): interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A>A> => ({
[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]() {
let let next: Bnext = b: Bb
return {
Iterator<A, any, any>.next(...[value]: [] | [any]): IteratorResult<A, any>next() {
const const ab: Option<readonly [A, B]>ab = f: (b: B) => Option<readonly [A, B]>f(let next: Bnext)
if (import OO.const isNone: <A>(
self: Option<A>
) => self is None<A>
Checks whether an Option is None (absent).
When to use
Use when you need to branch on an absent Option before accessing .value.
Details
- Acts as a type guard, narrowing to
None<A>
Example (Checking for None)
import { Option } from "effect"
console.log(Option.isNone(Option.some(1)))
// Output: false
console.log(Option.isNone(Option.none()))
// Output: true
isNone(const ab: Option<readonly [A, B]>ab)) {
return { IteratorReturnResult<TReturn>.done: truedone: true, IteratorReturnResult<any>.value: anyvalue: var undefinedundefined }
}
const [const a: Aa, const b: Bb] = const ab: O.Some<readonly [A, B]>const ab: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
ab.Some<readonly [A, B]>.value: readonly [A, B](property) Some<readonly [A, B]>.value: {
0: A;
1: B;
length: 2;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<B | A>>): Array<B | A>; (...items: Array<B | A | ConcatArray<B | A>>): Array<B | A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<B | A>;
indexOf: (searchElement: B | A, fromIndex?: number) => number;
lastIndexOf: (searchElement: B | A, fromIndex?: number) => number;
every: { (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: B | A, index: number, array: ReadonlyArray<B | A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: B | A, index: number, array: ReadonlyArray<B | A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => unknown, thisArg?: any): Array<B | A> };
reduce: { (callbackfn: (previousValue: B | A, currentValue: B | A, currentIndex: number, array: ReadonlyArray<B | A>) => B | A): B | A; (callbackfn: (previousValue: B | A, currentValue: B | A, currentIndex: number, array: ReadonlyArray<B | A>) => …;
reduceRight: { (callbackfn: (previousValue: B | A, currentValue: B | A, currentIndex: number, array: ReadonlyArray<B | A>) => B | A): B | A; (callbackfn: (previousValue: B | A, currentValue: B | A, currentIndex: number, array: ReadonlyArray<B | A>) => …;
find: { (predicate: (value: B | A, index: number, obj: ReadonlyArray<B | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: B | A, index: number, obj: ReadonlyArray<B | A>) => unknown, thisArg?: any): B | A | undefined };
findIndex: (predicate: (value: B | A, index: number, obj: ReadonlyArray<B | A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, B | A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<B | A>;
includes: (searchElement: B | A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: B | A, index: number, array: Array<B | A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => B | A | undefined;
findLast: { (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => unknown, thisArg?: any): B | A | undefined };
findLastIndex: (predicate: (value: B | A, index: number, array: ReadonlyArray<B | A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<B | A>;
toSorted: (compareFn?: ((a: B | A, b: B | A) => number) | undefined) => Array<B | A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<B | A>): Array<B | A>; (start: number, deleteCount?: number): Array<B | A> };
with: (index: number, value: B | A) => Array<B | A>;
}
value
let next: Bnext = const b: Bb
return { IteratorYieldResult<TYield>.done?: false | undefineddone: false, IteratorYieldResult<A>.value: Avalue: const a: Aa }
}
}
}
})