<S, A, E, R>(
s: S,
f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>
): Stream<A, E, R>Creates a stream by repeatedly applying an effectful step function to a state.
Details
Each readonly [value, nextState] result emits value and continues with
nextState; returning undefined ends the stream.
Example (Unfolding stream state)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
const stream = Stream.unfold(1, (n) => Effect.succeed([n, n + 1] as const))
const values = yield* Stream.runCollect(stream.pipe(Stream.take(5)))
yield* Console.log(values)
})
Effect.runPromise(program)
// Output: [ 1, 2, 3, 4, 5 ]export const const unfold: <S, A, E, R>(
s: S,
f: (
s: S
) => Effect.Effect<
readonly [A, S] | undefined,
E,
R
>
) => Stream<A, E, R>
Creates a stream by repeatedly applying an effectful step function to a
state.
Details
Each readonly [value, nextState] result emits value and continues with
nextState; returning undefined ends the stream.
Example (Unfolding stream state)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
const stream = Stream.unfold(1, (n) => Effect.succeed([n, n + 1] as const))
const values = yield* Stream.runCollect(stream.pipe(Stream.take(5)))
yield* Console.log(values)
})
Effect.runPromise(program)
// Output: [ 1, 2, 3, 4, 5 ]
unfold = <function (type parameter) S in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>S, function (type parameter) A in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>A, function (type parameter) E in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>E, function (type parameter) R in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>R>(
s: Ss: function (type parameter) S in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>S,
f: (
s: S
) => Effect.Effect<
readonly [A, S] | undefined,
E,
R
>
f: (s: Ss: function (type parameter) S in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>S) => import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<readonly [function (type parameter) A in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>A, function (type parameter) S in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>S] | undefined, function (type parameter) E in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>E, function (type parameter) R in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>R>
): interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) A in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>A, function (type parameter) E in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>E, function (type parameter) R in <S, A, E, R>(s: S, f: (s: S) => Effect.Effect<readonly [A, S] | undefined, E, R>): Stream<A, E, R>R> =>
const fromPull: <A, E, R, EX, RX>(
pull: Effect.Effect<
Pull.Pull<
Arr.NonEmptyReadonlyArray<A>,
E,
void,
R
>,
EX,
RX
>
) => Stream<A, Pull.ExcludeDone<E> | EX, R | RX>
Creates a stream from a pull effect, such as one produced by Stream.toPull.
Details
A pull effect yields chunks on demand and completes when the upstream stream ends.
See Stream.toPull for a matching producer.
Example (Creating a stream from a pull effect)
import { Console, Effect, Stream } from "effect"
const program = Effect.scoped(
Effect.gen(function*() {
const source = Stream.make(1, 2, 3)
const pull = yield* Stream.toPull(source)
const stream = Stream.fromPull(Effect.succeed(pull))
const values = yield* Stream.runCollect(stream)
yield* Console.log(values)
})
)
Effect.runPromise(program)
// Output: [1, 2, 3]
fromPull(import EffectEffect.sync(() => {
let let state: Sstate = s: Ss
return import EffectEffect.flatMap(import EffectEffect.suspend(() => f: (
s: S
) => Effect.Effect<
readonly [A, S] | undefined,
E,
R
>
f(let state: Sstate)), (next: anynext) => {
if (next: anynext === var undefinedundefined) return import CauseCause.done()
let state: Sstate = next: any(parameter) next: {
0: A;
1: S;
length: 2;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<S | A>>): Array<S | A>; (...items: Array<S | A | ConcatArray<S | A>>): Array<S | A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<S | A>;
indexOf: (searchElement: S | A, fromIndex?: number) => number;
lastIndexOf: (searchElement: S | A, fromIndex?: number) => number;
every: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: S | A, index: number, array: ReadonlyArray<S | A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: S | A, index: number, array: ReadonlyArray<S | A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): Array<S | A> };
reduce: { (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => S | A): S | A; (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => …;
reduceRight: { (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => S | A): S | A; (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => …;
find: { (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => unknown, thisArg?: any): S | A | undefined };
findIndex: (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, S | A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<S | A>;
includes: (searchElement: S | A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: S | A, index: number, array: Array<S | A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => S | A | undefined;
findLast: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): S | A | undefined };
findLastIndex: (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<S | A>;
toSorted: (compareFn?: ((a: S | A, b: S | A) => number) | undefined) => Array<S | A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<S | A>): Array<S | A>; (start: number, deleteCount?: number): Array<S | A> };
with: (index: number, value: S | A) => Array<S | A>;
}
next[1]
return import EffectEffect.succeed(import ArrArr.of(next: any(parameter) next: {
0: A;
1: S;
length: 2;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<S | A>>): Array<S | A>; (...items: Array<S | A | ConcatArray<S | A>>): Array<S | A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<S | A>;
indexOf: (searchElement: S | A, fromIndex?: number) => number;
lastIndexOf: (searchElement: S | A, fromIndex?: number) => number;
every: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: S | A, index: number, array: ReadonlyArray<S | A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: S | A, index: number, array: ReadonlyArray<S | A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): Array<S | A> };
reduce: { (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => S | A): S | A; (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => …;
reduceRight: { (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => S | A): S | A; (callbackfn: (previousValue: S | A, currentValue: S | A, currentIndex: number, array: ReadonlyArray<S | A>) => …;
find: { (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => unknown, thisArg?: any): S | A | undefined };
findIndex: (predicate: (value: S | A, index: number, obj: ReadonlyArray<S | A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, S | A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<S | A>;
includes: (searchElement: S | A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: S | A, index: number, array: Array<S | A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => S | A | undefined;
findLast: { (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any): S | A | undefined };
findLastIndex: (predicate: (value: S | A, index: number, array: ReadonlyArray<S | A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<S | A>;
toSorted: (compareFn?: ((a: S | A, b: S | A) => number) | undefined) => Array<S | A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<S | A>): Array<S | A>; (start: number, deleteCount?: number): Array<S | A> };
with: (index: number, value: S | A) => Array<S | A>;
}
next[0]))
})
}))