Introduction to Streams
The Stream
type is an immutable description of a potentially unbounded sequence of values, handled within a context and capable of error management.
Here is the general form of an Stream
:
┌─── Success type │ ┌─── Error type │ │ ┌─── Requirements ▼ ▼ ▼Stream<Success, Error, Requirements>
When executed, a Stream
can emit zero or more values of type Success
, handle errors of type Error
, and operate within a context of type Requirements
.
Streams are well-suited for managing sequences of values over time and are a great fit as alternatives to observables, Node streams, and AsyncIterables. You can think of a Stream
as an Effect
that can yield multiple values instead of a single result.
Unlike an Effect
, which always resolves to one specific value, a Stream
offers greater flexibility, allowing for:
- Empty Streams: Streams that produce no values.
- Single-Element Streams: Streams that emit only one value.
- Finite Streams: Streams with a defined number of elements.
- Infinite Streams: Streams that emit values continuously.
Example (Creating Different Stream Types)
1import { import Stream
Stream } from "effect"2
3// An empty Stream4const const emptyStream: Stream.Stream<never, never, never>
emptyStream = import Stream
Stream.const empty: Stream.Stream<never, never, never>
The empty stream.
empty5
6// A Stream with a single number7const const oneNumberValueStream: Stream.Stream<number, never, never>
oneNumberValueStream = import Stream
Stream.const succeed: <number>(value: number) => Stream.Stream<number, never, never>
Creates a single-valued pure stream.
succeed(3)8
9// A Stream with numbers from 1 to 1010const const finiteNumberStream: Stream.Stream<number, never, never>
finiteNumberStream = import Stream
Stream.const range: (min: number, max: number, chunkSize?: number) => Stream.Stream<number>
Constructs a stream from a range of integers, including both endpoints.
range(1, 10)11
12// An infinite Stream of numbers starting from 1 and incrementing13const const infiniteNumberStream: Stream.Stream<number, never, never>
infiniteNumberStream = import Stream
Stream.const iterate: <number>(value: number, next: (value: number) => number) => Stream.Stream<number, never, never>
The infinite stream of iterative function application: a, f(a), f(f(a)),
f(f(f(a))), ...
iterate(1, ((parameter) n: number
n) => (parameter) n: number
n + 1)