In this guide, we’ll explore the concept of a Stream<A, E, R>. A Stream is a program description that, when executed, can emit zero or more values of type A, handle errors of type E, and operates within a context of type R.
Use Cases
Streams are particularly handy whenever you’re dealing with sequences of values over time. They can serve as replacements for observables, node streams, and AsyncIterables.
What is a Stream?
Think of a Stream as an extension of an Effect. While an Effect<A, E, R> represents a program that requires a context of type R, may encounter an error of type E, and always produces a single result of type A, a Stream<A, E, R> takes this further by allowing the emission of zero or more values of type A.
To clarify, let’s examine some examples using Effect:
Creates an Effect that represents a recoverable error.
When to Use
Use this function to explicitly signal an error in an Effect. The error
will keep propagating unless it is handled. You can handle the error with
functions like
catchAll
or
catchTag
.
@see ― succeed to create an effect that represents a successful value.
In each case, the Effect always ends with exactly one value. There is no variability; you always get one result.
Understanding Streams
Now, let’s shift our focus to Stream. A Stream represents a program description that shares similarities with Effect, it requires a context of type R, may signal errors of type E, and yields values of type A. However, the key distinction is that it can yield zero or more values.
Here are the possible scenarios for a Stream:
An Empty Stream: It can end up empty, representing a stream with no values.
A Single-Element Stream: It can represent a stream with just one value.
A Finite Stream of Elements: It can represent a stream with a finite number of values.
An Infinite Stream of Elements: It can represent a stream that continues indefinitely, essentially an infinite stream.
In summary, a Stream is a versatile tool for representing programs that may yield multiple values, making it suitable for a wide range of tasks, from processing finite lists to handling infinite sequences.