A stream producing output of type O
and which may evaluate F
effects.
-
'''Purely functional''' a value of type
Stream[F, O]
describes an effectful computation. A function that returns aStream[F, O]
builds a description of an effectful computation, but does not perform them. The methods of theStream
class derive new descriptions from others. This is similar to how effect types likecats.effect.IO
andmonix.Task
build descriptions of computations. -
'''Pull''': to evaluate a stream, a consumer pulls its values from it, by repeatedly performing one pull step at a time. Each step is a
F
-effectful computation that may yield someO
values (or none), and a stream from which to continue pulling. The consumer controls the evaluation of the stream, which effectful operations are performed, and when. -
'''Non-Strict''': stream evaluation only pulls from the stream a prefix large enough to compute its results. Thus, although a stream may yield an unbounded number of values or, after successfully yielding several values, either raise an error or hang up and never yield any value, the consumer need not reach those points of failure. For the same reason, in general, no effect in
F
is evaluated unless and until the consumer needs it. -
'''Abstract''': a stream needs not be a plain finite list of fixed effectful computations in F. It can also represent an input or output connection through which data incrementally arrives. It can represent an effectful computation, such as reading the system's time, that can be re-evaluated as often as the consumer of the stream requires.
=== Special properties for streams ===
There are some special properties or cases of streams:
- A stream is '''finite''' if we can reach the end after a limited number of pull steps, which may yield a finite number of values. It is '''empty''' if it terminates and yields no values.
- A '''singleton''' stream is a stream that ends after yielding one single value.
- A '''pure''' stream is one in which the
F
is Pure, which indicates that it evaluates no effects. - A '''never''' stream is a stream that never terminates and never yields any value.
== Pure Streams and operations ==
We can sometimes think of streams, naively, as lists of O
elements with F
-effects.
This is particularly true for '''pure''' streams, which are instances of Stream
which use the Pure effect type.
We can convert every ''pure and finite'' stream into a List[O]
using the .toList
method.
Also, we can convert pure ''infinite'' streams into instances of the Stream[O]
class from the Scala standard library.
A method of the Stream
class is '''pure''' if it can be applied to pure streams. Such methods are identified
in that their signature includes no type-class constraint (or implicit parameter) on the F
method.
Pure methods in Stream[F, O]
can be projected ''naturally'' to methods in the List
class, which means
that applying the stream's method and converting the result to a list gets the same result as
first converting the stream to a list, and then applying list methods.
Some methods that project directly to list are map
, filter
, takeWhile
, etc.
There are other methods, like exists
or find
, that in the List
class they return a value or an Option
,
but their stream counterparts return an (either empty or singleton) stream.
Other methods, like zipWithPrevious
, have a more complicated but still pure translation to list methods.
== Type-Class instances and laws of the Stream Operations ==
Laws (using infix syntax):
append
forms a monoid in conjunction with empty
:
empty append s == s
ands append empty == s
.(s1 append s2) append s3 == s1 append (s2 append s3)
And cons
is consistent with using ++
to prepend a single chunk:
s.cons(c) == Stream.chunk(c) ++ s
Stream.raiseError
propagates until being caught by handleErrorWith
:
Stream.raiseError(e) handleErrorWith h == h(e)
Stream.raiseError(e) ++ s == Stream.raiseError(e)
Stream.raiseError(e) flatMap f == Stream.raiseError(e)
Stream
forms a monad with emit
and flatMap
:
Stream.emit >=> f == f
(left identity)f >=> Stream.emit === f
(right identity - note weaker equality notion here)(f >=> g) >=> h == f >=> (g >=> h)
(associativity) whereStream.emit(a)
is defined aschunk(Chunk.singleton(a)) and
f >=> gis defined as
a => a flatMap f flatMap g`
The monad is the list-style sequencing monad:
(a ++ b) flatMap f == (a flatMap f) ++ (b flatMap f)
Stream.empty flatMap f == Stream.empty
== Technical notes==
''Note:'' since the chunk structure of the stream is observable, and
s flatMap Stream.emit
produces a stream of singleton chunks,
the right identity law uses a weaker notion of equality, ===
which
normalizes both sides with respect to chunk structure:
(s1 === s2) = normalize(s1) == normalize(s2)
where ==
is full equality
(a == b
iff f(a)
is identical to f(b)
for all f
)
normalize(s)
can be defined as s.flatMap(Stream.emit)
, which just
produces a singly-chunked stream from any input stream s
.
For instance, for a stream s
and a function f: A => B
,
- the result of
s.map(f)
is a Stream with the same chunking as thes
; whereas... - the result of
s.flatMap(x => S.emit(f(x)))
is a Stream structured as a sequence of singleton chunks. The latter is using the definition ofmap
that is derived from theMonad
instance.
This is not unlike equality for maps or sets, which is defined by which elements they contain,
not by how these are spread between a tree's branches or a hashtable buckets.
However, a Stream
structure can be observed through the chunks
method,
so two streams "equal" under that notion may give different results through this method.
''Note:'' For efficiency [[Stream.map]]
function operates on an entire
chunk at a time and preserves chunk structure, which differs from
the map
derived from the monad (s map f == s flatMap (f andThen Stream.emit)
)
which would produce singleton chunk. In particular, if f
throws errors, the
chunked version will fail on the first ''chunk'' with an error, while
the unchunked version will fail on the first ''element'' with an error.
Exceptions in pure code like this are strongly discouraged.
- Companion
- object
Value members
Concrete methods
Appends s2
to the end of this stream.
Appends s2
to the end of this stream.
- Example
scala> (Stream(1,2,3) ++ Stream(4,5,6)).toList res0: List[Int] = List(1, 2, 3, 4, 5, 6)
If
this
stream is infinite, then the result is equivalent tothis
.
Appends s2
to the end of this stream. Alias for s1 ++ s2
.
Appends s2
to the end of this stream. Alias for s1 ++ s2
.
Equivalent to val o2Memoized = o2; _.map(_ => o2Memoized)
.
Equivalent to val o2Memoized = o2; _.map(_ => o2Memoized)
.
- Example
scala> Stream(1,2,3).as(0).toList res0: List[Int] = List(0, 0, 0)
Returns a stream of O
values wrapped in Right
until the first error, which is emitted wrapped in Left
.
Returns a stream of O
values wrapped in Right
until the first error, which is emitted wrapped in Left
.
- Example
scala> import cats.effect.SyncIO scala> (Stream(1,2,3) ++ Stream.raiseError[SyncIO](new RuntimeException) ++ Stream(4,5,6)).attempt.compile.toList.unsafeRunSync() res0: List[Either[Throwable,Int]] = List(Right(1), Right(2), Right(3), Left(java.lang.RuntimeException))
rethrow is the inverse of
attempt
, with the caveat that anything after the first failure is discarded.
Retries on failure, returning a stream of attempts that can
be manipulated with standard stream operations such as take
,
collectFirst
and interruptWhen
.
Retries on failure, returning a stream of attempts that can
be manipulated with standard stream operations such as take
,
collectFirst
and interruptWhen
.
Note: The resulting stream does not automatically halt at the
first successful attempt. Also see retry
.
Broadcasts every value of the stream through the pipes provided as arguments.
Broadcasts every value of the stream through the pipes provided as arguments.
Each pipe can have a different implementation if required, and
they are all guaranteed to see every O
pulled from the source
stream.
The pipes are all run concurrently with each other, but note that elements are pulled from the source as chunks, and the next chunk is pulled only when all pipes are done with processing the current chunk, which prevents faster pipes from getting too far ahead.
In other words, this behaviour slows down processing of incoming
chunks by faster pipes until the slower ones have caught up. If
this is not desired, consider using the prefetch
and
prefetchN
combinators on the slow pipes.
Behaves like the identity function, but requests n
elements at a time from the input.
Behaves like the identity function, but requests n
elements at a time from the input.
- Example
scala> import cats.effect.SyncIO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 100).covary[SyncIO]. | evalMap(i => SyncIO { buf += s">$i"; i }). | buffer(4). | evalMap(i => SyncIO { buf += s"<$i"; i }). | take(10). | compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) scala> buf.toList res1: List[String] = List(>0, >1, >2, >3, <0, <1, <2, <3, >4, >5, >6, >7, <4, <5, <6, <7, >8, >9, >10, >11, <8, <9)
Behaves like the identity stream, but emits no output until the source is exhausted.
Behaves like the identity stream, but emits no output until the source is exhausted.
- Example
scala> import cats.effect.SyncIO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 10).covary[SyncIO]. | evalMap(i => SyncIO { buf += s">$i"; i }). | bufferAll. | evalMap(i => SyncIO { buf += s"<$i"; i }). | take(4). | compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 2, 3) scala> buf.toList res1: List[String] = List(>0, >1, >2, >3, >4, >5, >6, >7, >8, >9, <0, <1, <2, <3)
Behaves like the identity stream, but requests elements from its input in blocks that end whenever the predicate switches from true to false.
Behaves like the identity stream, but requests elements from its input in blocks that end whenever the predicate switches from true to false.
- Example
scala> import cats.effect.SyncIO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 10).covary[SyncIO]. | evalMap(i => SyncIO { buf += s">$i"; i }). | bufferBy(_ % 2 == 0). | evalMap(i => SyncIO { buf += s"<$i"; i }). | compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) scala> buf.toList res1: List[String] = List(>0, >1, <0, <1, >2, >3, <2, <3, >4, >5, <4, <5, >6, >7, <6, <7, >8, >9, <8, <9)
Emits only elements that are distinct from their immediate predecessors, using natural equality for comparison.
Emits only elements that are distinct from their immediate predecessors, using natural equality for comparison.
- Example
scala> Stream(1,1,2,2,2,3,3).changes.toList res0: List[Int] = List(1, 2, 3)
Emits only elements that are distinct from their immediate predecessors
according to f
, using natural equality for comparison.
Emits only elements that are distinct from their immediate predecessors
according to f
, using natural equality for comparison.
Note that f
is called for each element in the stream multiple times
and hence should be fast (e.g., an accessor). It is not intended to be
used for computationally intensive conversions. For such conversions,
consider something like: src.map(o => (o, f(o))).changesBy(_._2).map(_._1)
- Example
scala> Stream(1,1,2,4,6,9).changesBy(_ % 2).toList res0: List[Int] = List(1, 2, 9)
Collects all output chunks in to a single chunk and emits it at the end of the source stream. Note: if more than 2^32-1 elements are collected, this operation will fail.
Collects all output chunks in to a single chunk and emits it at the end of the source stream. Note: if more than 2^32-1 elements are collected, this operation will fail.
- Example
scala> (Stream(1) ++ Stream(2, 3) ++ Stream(4, 5, 6)).chunkAll.toList res0: List[Chunk[Int]] = List(Chunk(1, 2, 3, 4, 5, 6))
Outputs chunk with a limited maximum size, splitting as necessary.
Outputs chunk with a limited maximum size, splitting as necessary.
- Example
scala> (Stream(1) ++ Stream(2, 3) ++ Stream(4, 5, 6)).chunkLimit(2).toList res0: List[Chunk[Int]] = List(Chunk(1), Chunk(2, 3), Chunk(4, 5), Chunk(6))
Outputs chunks of size larger than N
Outputs chunks of size larger than N
Chunks from the source stream are split as necessary.
If allowFewerTotal
is true,
if the stream is smaller than N, should the elements be included
- Example
scala> (Stream(1,2) ++ Stream(3,4) ++ Stream(5,6,7)).chunkMin(3).toList res0: List[Chunk[Int]] = List(Chunk(1, 2, 3, 4), Chunk(5, 6, 7))
Outputs chunks of size n
.
Outputs chunks of size n
.
Chunks from the source stream are split as necessary.
If allowFewer
is true, the last chunk that is emitted may have less than n
elements.
- Example
scala> Stream(1,2,3).repeat.chunkN(2).take(5).toList res0: List[Chunk[Int]] = List(Chunk(1, 2), Chunk(3, 1), Chunk(2, 3), Chunk(1, 2), Chunk(3, 1))
Outputs all chunks from the source stream.
Outputs all chunks from the source stream.
- Example
scala> (Stream(1) ++ Stream(2, 3) ++ Stream(4, 5, 6)).chunks.toList res0: List[Chunk[Int]] = List(Chunk(1), Chunk(2, 3), Chunk(4, 5, 6))
Filters and maps simultaneously. Calls collect
on each chunk in the stream.
Filters and maps simultaneously. Calls collect
on each chunk in the stream.
- Example
scala> Stream(Some(1), Some(2), None, Some(3), None, Some(4)).collect { case Some(i) => i }.toList res0: List[Int] = List(1, 2, 3, 4)
Emits the first element of the stream for which the partial function is defined.
Emits the first element of the stream for which the partial function is defined.
- Example
scala> Stream(None, Some(1), Some(2), None, Some(3)).collectFirst { case Some(i) => i }.toList res0: List[Int] = List(1)
Gets a projection of this stream that allows converting it to an F[..]
in a number of ways.
Gets a projection of this stream that allows converting it to an F[..]
in a number of ways.
- Example
scala> import cats.effect.SyncIO scala> val prg: SyncIO[Vector[Int]] = Stream.eval(SyncIO(1)).append(Stream(2,3,4)).compile.toVector scala> prg.unsafeRunSync() res2: Vector[Int] = Vector(1, 2, 3, 4)
Runs the supplied stream in the background as elements from this stream are pulled.
Runs the supplied stream in the background as elements from this stream are pulled.
The resulting stream terminates upon termination of this stream. The background stream will
be interrupted at that point. Early termination of that
does not terminate the resulting stream.
Any errors that occur in either this
or that
stream result in the overall stream terminating
with an error.
Upon finalization, the resulting stream will interrupt the background stream and wait for it to be finalized.
This method is equivalent to this mergeHaltL that.drain
, just more efficient for this
and that
evaluation.
- Example
scala> import cats.effect.IO, cats.effect.unsafe.implicits.global scala> val data: Stream[IO,Int] = Stream.range(1, 10).covary[IO] scala> Stream.eval(fs2.concurrent.SignallingRef[IO,Int](0)).flatMap(s => Stream(s).concurrently(data.evalMap(s.set))).flatMap(_.discrete).takeWhile(_ < 9, true).compile.last.unsafeRunSync() res0: Option[Int] = Some(9)
Prepends a chunk onto the front of this stream.
Prepends a chunk onto the front of this stream.
- Example
scala> Stream(1,2,3).cons(Chunk(-1, 0)).toList res0: List[Int] = List(-1, 0, 1, 2, 3)
Prepends a single value onto the front of this stream.
Prepends a single value onto the front of this stream.
- Example
scala> Stream(1,2,3).cons1(0).toList res0: List[Int] = List(0, 1, 2, 3)
Prepends a chunk onto the front of this stream.
Prepends a chunk onto the front of this stream.
- Example
scala> Stream(1,2,3).consChunk(Chunk.vector(Vector(-1, 0))).toList res0: List[Int] = List(-1, 0, 1, 2, 3)
Lifts this stream to the specified effect and output types.
Lifts this stream to the specified effect and output types.
- Example
scala> import cats.effect.IO scala> Stream.empty.covaryAll[IO,Int] res0: Stream[IO,Int] = Stream(..)
Lifts this stream to the specified output type.
Lifts this stream to the specified output type.
- Example
scala> Stream(Some(1), Some(2), Some(3)).covaryOutput[Option[Int]] res0: Stream[Pure,Option[Int]] = Stream(..)
Debounce the stream with a minimum period of d
between each element.
Debounce the stream with a minimum period of d
between each element.
Use-case: if this is a stream of updates about external state, we may want to refresh (side-effectful) once every 'd' milliseconds, and every time we refresh we only care about the latest update.
- Returns
A stream whose values is an in-order, not necessarily strict subsequence of this stream, and whose evaluation will force a delay
d
between emitting each element. The exact subsequence would depend on the chunk structure of this stream, and the timing they arrive.- Example
scala> import scala.concurrent.duration._, cats.effect.IO, cats.effect.unsafe.implicits.global scala> val s = Stream(1, 2, 3) ++ Stream.sleep_[IO](500.millis) ++ Stream(4, 5) ++ Stream.sleep_[IO](10.millis) ++ Stream(6) scala> val s2 = s.debounce(100.milliseconds) scala> s2.compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(3, 6)
Logs the elements of this stream as they are pulled.
Logs the elements of this stream as they are pulled.
By default, toString
is called on each element and the result is printed
to standard out. To change formatting, supply a value for the formatter
param. To change the destination, supply a value for the logger
param.
This method does not change the chunk structure of the stream. To debug the chunk structure, see debugChunks.
Logging is not done in F
because this operation is intended for debugging,
including pure streams.
- Example
scala> Stream(1, 2).append(Stream(3, 4)).debug(o => s"a: $o").toList a: 1 a: 2 a: 3 a: 4 res0: List[Int] = List(1, 2, 3, 4)
Like debug but logs chunks as they are pulled instead of individual elements.
Like debug but logs chunks as they are pulled instead of individual elements.
- Example
scala> Stream(1, 2, 3).append(Stream(4, 5, 6)).debugChunks(c => s"a: $c").buffer(2).debugChunks(c => s"b: $c").toList a: Chunk(1, 2, 3) b: Chunk(1, 2) a: Chunk(4, 5, 6) b: Chunk(3, 4) b: Chunk(5, 6) res0: List[Int] = List(1, 2, 3, 4, 5, 6)
Returns a stream that when run, sleeps for duration d
and then pulls from this stream.
Returns a stream that when run, sleeps for duration d
and then pulls from this stream.
Alias for sleep_[F](d) ++ this
.
Skips the first element that matches the predicate.
Skips the first element that matches the predicate.
- Example
scala> Stream.range(1, 10).delete(_ % 2 == 0).toList res0: List[Int] = List(1, 3, 4, 5, 6, 7, 8, 9)
Removes all output values from this stream.
Removes all output values from this stream.
Often used with merge
to run one side of the merge for its effect
while getting outputs from the opposite side of the merge.
- Example
scala> import cats.effect.SyncIO scala> Stream.eval(SyncIO(println("x"))).drain.compile.toVector.unsafeRunSync() res0: Vector[INothing] = Vector()
Drops n
elements of the input, then echoes the rest.
Drops n
elements of the input, then echoes the rest.
- Example
scala> Stream.range(0,10).drop(5).toList res0: List[Int] = List(5, 6, 7, 8, 9)
Drops the last element.
Drops the last element.
- Example
scala> Stream.range(0,10).dropLast.toList res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8)
Drops the last element if the predicate evaluates to true.
Drops the last element if the predicate evaluates to true.
- Example
scala> Stream.range(0,10).dropLastIf(_ > 5).toList res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8)
Outputs all but the last n
elements of the input.
Outputs all but the last n
elements of the input.
This is a '''pure''' stream operation: if s
is a finite pure stream, then s.dropRight(n).toList
is equal to this.toList.reverse.drop(n).reverse
.
- Example
scala> Stream.range(0,10).dropRight(5).toList res0: List[Int] = List(0, 1, 2, 3, 4)
Like dropWhile, but drops the first value which tests false.
Like dropWhile, but drops the first value which tests false.
- Example
scala> Stream.range(0,10).dropThrough(_ != 4).toList res0: List[Int] = List(5, 6, 7, 8, 9)
'''Pure:''' if
this
is a finite pure stream, thenthis.dropThrough(p).toList
is equal tothis.toList.dropWhile(p).drop(1)
Drops elements from the head of this stream until the supplied predicate returns false.
Drops elements from the head of this stream until the supplied predicate returns false.
- Example
scala> Stream.range(0,10).dropWhile(_ != 4).toList res0: List[Int] = List(4, 5, 6, 7, 8, 9)
'''Pure''' this operation maps directly to
List.dropWhile
Like [[merge]]
, but tags each output with the branch it came from.
Like [[merge]]
, but tags each output with the branch it came from.
- Example
scala> import scala.concurrent.duration._, cats.effect.IO, cats.effect.unsafe.implicits.global scala> val s1 = Stream.awakeEvery[IO](1000.millis).scan(0)((acc, _) => acc + 1) scala> val s = s1.either(Stream.sleep_[IO](500.millis) ++ s1).take(10) scala> s.take(10).compile.toVector.unsafeRunSync() res0: Vector[Either[Int,Int]] = Vector(Left(0), Right(0), Left(1), Right(1), Left(2), Right(2), Left(3), Right(3), Left(4), Right(4))
Enqueues the elements of this stream to the supplied queue and enqueues None
when this stream terminates.
Enqueues the elements of this stream to the supplied queue and enqueues None
when this stream terminates.
Enqueues the chunks of this stream to the supplied queue and enqueues None
when this stream terminates.
Enqueues the chunks of this stream to the supplied queue and enqueues None
when this stream terminates.
Enqueues the elements of this stream to the supplied queue.
Enqueues the elements of this stream to the supplied queue.
Enqueues the chunks of this stream to the supplied queue.
Enqueues the chunks of this stream to the supplied queue.
Like filter
, but allows filtering based on an effect.
Like filter
, but allows filtering based on an effect.
Note: The result Stream will consist of chunks that are empty or 1-element-long. If you want to operate on chunks after using it, consider buffering, e.g. by using buffer.
Like filter
, but allows filtering based on an effect, with up to maxConcurrent concurrently running effects.
The ordering of emitted elements is unchanged.
Like filter
, but allows filtering based on an effect, with up to maxConcurrent concurrently running effects.
The ordering of emitted elements is unchanged.
Like filterNot
, but allows filtering based on an effect.
Like filterNot
, but allows filtering based on an effect.
Note: The result Stream will consist of chunks that are empty or 1-element-long. If you want to operate on chunks after using it, consider buffering, e.g. by using buffer.
Like filterNot
, but allows filtering based on an effect, with up to maxConcurrent concurrently running effects.
The ordering of emitted elements is unchanged.
Like filterNot
, but allows filtering based on an effect, with up to maxConcurrent concurrently running effects.
The ordering of emitted elements is unchanged.
Alias for flatMap(o => Stream.eval(f(o)))
.
Alias for flatMap(o => Stream.eval(f(o)))
.
- Example
scala> import cats.effect.SyncIO scala> Stream(1,2,3,4).evalMap(i => SyncIO(println(i))).compile.drain.unsafeRunSync() res0: Unit = ()
Note this operator will de-chunk the stream back into chunks of size 1, which has performance implications. For maximum performance,
evalMapChunk
is available, however, with caveats.
Like [[Stream#mapAccumulate]]
, but accepts a function returning an F[_]
.
Like [[Stream#mapAccumulate]]
, but accepts a function returning an F[_]
.
- Example
scala> import cats.effect.SyncIO scala> Stream(1,2,3,4).covary[SyncIO].evalMapAccumulate(0)((acc,i) => SyncIO((i, acc + i))).compile.toVector.unsafeRunSync() res0: Vector[(Int, Int)] = Vector((1,1), (2,3), (3,5), (4,7))
Like evalMap
, but operates on chunks for performance. This means this operator
is not lazy on every single element, rather on the chunks.
Like evalMap
, but operates on chunks for performance. This means this operator
is not lazy on every single element, rather on the chunks.
For instance, evalMap
would only print twice in the follow example (note the take(2)
):
- Example
scala> import cats.effect.SyncIO scala> Stream(1,2,3,4).evalMap(i => SyncIO(println(i))).take(2).compile.drain.unsafeRunSync() res0: Unit = ()
But with
evalMapChunk
, it will print 4 times:scala> Stream(1,2,3,4).evalMapChunk(i => SyncIO(println(i))).take(2).compile.drain.unsafeRunSync() res0: Unit = ()
Effectfully maps and filters the elements of the stream depending on the optionality of the result of the
application of the effectful function f
.
Effectfully maps and filters the elements of the stream depending on the optionality of the result of the
application of the effectful function f
.
- Example
scala> import cats.effect.SyncIO, cats.syntax.all._ scala> Stream(1, 2, 3, 4, 5).evalMapFilter(n => SyncIO((n * 2).some.filter(_ % 4 == 0))).compile.toList.unsafeRunSync() res0: List[Int] = List(4, 8)
Like [[Stream#scan]]
, but accepts a function returning an F[_]
.
Like [[Stream#scan]]
, but accepts a function returning an F[_]
.
- Example
scala> import cats.effect.SyncIO scala> Stream(1,2,3,4).covary[SyncIO].evalScan(0)((acc,i) => SyncIO(acc + i)).compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 3, 6, 10)
Like observe
but observes with a function O => F[O2]
instead of a pipe.
Not as powerful as observe
since not all pipes can be represented by O => F[O2]
, but much faster.
Alias for evalMap(o => f(o).as(o))
.
Like observe
but observes with a function O => F[O2]
instead of a pipe.
Not as powerful as observe
since not all pipes can be represented by O => F[O2]
, but much faster.
Alias for evalMap(o => f(o).as(o))
.
Emits true
as soon as a matching element is received, else false
if no input matches.
'''Pure''': this operation maps to List.exists
Emits true
as soon as a matching element is received, else false
if no input matches.
'''Pure''': this operation maps to List.exists
- Returns
Either a singleton stream, or a
never
stream.- If
this
is a finite stream, the result is a singleton stream, with after yielding one single value. Ifthis
is empty, that value is themempty
of the instance ofMonoid
. - If
this
is a non-terminating stream, and no matter if it yields any value, then the result is equivalent to theStream.never
: it never terminates nor yields any value.
- If
- Example
scala> Stream.range(0,10).exists(_ == 4).toList res0: List[Boolean] = List(true) scala> Stream.range(0,10).exists(_ == 10).toList res1: List[Boolean] = List(false)
Emits only inputs which match the supplied predicate.
Emits only inputs which match the supplied predicate.
This is a '''pure''' operation, that projects directly into List.filter
- Example
scala> Stream.range(0,10).filter(_ % 2 == 0).toList res0: List[Int] = List(0, 2, 4, 6, 8)
Like filter
, but the predicate f
depends on the previously emitted and
current elements.
Like filter
, but the predicate f
depends on the previously emitted and
current elements.
- Example
scala> Stream(1, -1, 2, -2, 3, -3, 4, -4).filterWithPrevious((previous, current) => previous < current).toList res0: List[Int] = List(1, 2, 3, 4)
Emits the first input (if any) which matches the supplied predicate.
Emits the first input (if any) which matches the supplied predicate.
- Example
scala> Stream.range(1,10).find(_ % 2 == 0).toList res0: List[Int] = List(2)
'''Pure''' if
s
is a finite pure stream,s.find(p).toList
is equal tos.toList.find(p).toList
, where the secondtoList
is to turnOption
intoList
.
Creates a stream whose elements are generated by applying f
to each output of
the source stream and concatenated all of the results.
Creates a stream whose elements are generated by applying f
to each output of
the source stream and concatenated all of the results.
- Example
scala> Stream(1, 2, 3).flatMap { i => Stream.chunk(Chunk.seq(List.fill(i)(i))) }.toList res0: List[Int] = List(1, 2, 2, 3, 3, 3)
Flattens a stream of streams in to a single stream by concatenating each stream. See parJoin and parJoinUnbounded for concurrent flattening of 'n' streams.
Flattens a stream of streams in to a single stream by concatenating each stream. See parJoin and parJoinUnbounded for concurrent flattening of 'n' streams.
Folds all inputs using an initial value z
and supplied binary operator,
and emits a single element stream.
Folds all inputs using an initial value z
and supplied binary operator,
and emits a single element stream.
- Example
scala> Stream(1, 2, 3, 4, 5).fold(0)(_ + _).toList res0: List[Int] = List(15)
Folds all inputs using the supplied binary operator, and emits a single-element stream, or the empty stream if the input is empty, or the never stream if the input is non-terminating.
Folds all inputs using the supplied binary operator, and emits a single-element stream, or the empty stream if the input is empty, or the never stream if the input is non-terminating.
- Example
scala> Stream(1, 2, 3, 4, 5).fold1(_ + _).toList res0: List[Int] = List(15)
Alias for map(f).foldMonoid
.
Alias for map(f).foldMonoid
.
- Example
scala> Stream(1, 2, 3, 4, 5).foldMap(_ => 1).toList res0: List[Int] = List(5)
Folds this stream with the monoid for O
.
Folds this stream with the monoid for O
.
- Returns
Either a singleton stream or a
never
stream:- If
this
is a finite stream, the result is a singleton stream. Ifthis
is empty, that value is themempty
of the instance ofMonoid
. - If
this
is a non-terminating stream, and no matter if it yields any value, then the result is equivalent to theStream.never
: it never terminates nor yields any value.
- If
- Example
scala> Stream(1, 2, 3, 4, 5).foldMonoid.toList res0: List[Int] = List(15)
Emits false
and halts as soon as a non-matching element is received; or
emits a single true
value if it reaches the stream end and every input before that matches the predicate;
or hangs without emitting values if the input is infinite and all inputs match the predicate.
Emits false
and halts as soon as a non-matching element is received; or
emits a single true
value if it reaches the stream end and every input before that matches the predicate;
or hangs without emitting values if the input is infinite and all inputs match the predicate.
- Returns
Either a singleton or a never stream:
- '''If'''
this
yields an elementx
for which¬ p(x)
, '''then''' a singleton stream with the valuefalse
. Pulling from the resultg performs all the effects needed until reaching the counterexamplex
. - If
this
is a finite stream with no counterexamples ofp
, '''then''' a singleton stream with thetrue
value. Pulling from the it will perform all effects ofthis
. - If
this
is an infinite stream and all its the elements satisfyp
, then the result is anever
stream. Pulling from that stream will pull all effects fromthis
.
- '''If'''
- Example
scala> Stream(1, 2, 3, 4, 5).forall(_ < 10).toList res0: List[Boolean] = List(true)
Like evalMap
but discards the result of evaluation, resulting
in a stream with no elements.
Like evalMap
but discards the result of evaluation, resulting
in a stream with no elements.
- Example
scala> import cats.effect.SyncIO scala> Stream(1,2,3,4).foreach(i => SyncIO(println(i))).compile.drain.unsafeRunSync() res0: Unit = ()
Partitions the input into a stream of chunks according to a discriminator function.
Partitions the input into a stream of chunks according to a discriminator function.
Each chunk in the source stream is grouped using the supplied discriminator function and the results of the grouping are emitted each time the discriminator function changes values.
Note: there is no limit to how large a group can become. To limit the group size, use groupAdjacentByLimit.
- Example
scala> Stream("Hello", "Hi", "Greetings", "Hey").groupAdjacentBy(_.head).toList.map { case (k,vs) => k -> vs.toList } res0: List[(Char,List[String])] = List((H,List(Hello, Hi)), (G,List(Greetings)), (H,List(Hey)))
Like groupAdjacentBy but limits the size of emitted chunks.
Like groupAdjacentBy but limits the size of emitted chunks.
- Example
scala> Stream.range(0, 12).groupAdjacentByLimit(3)(_ / 4).toList res0: List[(Int,Chunk[Int])] = List((0,Chunk(0, 1, 2)), (0,Chunk(3)), (1,Chunk(4, 5, 6)), (1,Chunk(7)), (2,Chunk(8, 9, 10)), (2,Chunk(11)))
Divides this stream into chunks of elements of size n
.
Each time a group of size n
is emitted, timeout
is reset.
Divides this stream into chunks of elements of size n
.
Each time a group of size n
is emitted, timeout
is reset.
If the current chunk does not reach size n
by the time the
timeout
period elapses, it emits a chunk containing however
many elements have been accumulated so far, and resets
timeout
.
However, if no elements at all have been accumulated when
timeout
expires, empty chunks are not emitted, and timeout
is not reset.
Instead, the next chunk to arrive is emitted immediately (since
the stream is still in a timed out state), and only then is
timeout
reset. If the chunk received in a timed out state is
bigger than n
, the first n
elements of it are emitted
immediately in a chunk, timeout
is reset, and the remaining
elements are used for the next chunk.
When the stream terminates, any accumulated elements are emitted
immediately in a chunk, even if timeout
has not expired.
If this
terminates with Stream.raiseError(e)
, invoke h(e)
.
If this
terminates with Stream.raiseError(e)
, invoke h(e)
.
- Example
scala> import cats.effect.SyncIO scala> Stream(1, 2, 3).append(Stream.raiseError[SyncIO](new RuntimeException)).handleErrorWith(_ => Stream(0)).compile.toList.unsafeRunSync() res0: List[Int] = List(1, 2, 3, 0)
Emits the first element of this stream (if non-empty) and then halts.
Emits the first element of this stream (if non-empty) and then halts.
- Example
scala> Stream(1, 2, 3).head.toList res0: List[Int] = List(1)
Converts a discrete stream to a signal. Returns a single-element stream.
Converts a discrete stream to a signal. Returns a single-element stream.
Resulting signal is initially initial
, and is updated with latest value
produced by source
. If the source stream is empty, the resulting signal
will always be initial
.
Like holdResource but does not require an initial value,
and hence all output elements are wrapped in Some
.
Like holdResource but does not require an initial value,
and hence all output elements are wrapped in Some
.
Falls back to the supplied stream if this stream finishes without emitting any elements. Note: fallback occurs any time stream evaluation finishes without emitting, even when effects have been evaluated.
Falls back to the supplied stream if this stream finishes without emitting any elements. Note: fallback occurs any time stream evaluation finishes without emitting, even when effects have been evaluated.
- Example
scala> Stream.empty.ifEmpty(Stream(1, 2, 3)).toList res0: List[Int] = List(1, 2, 3) scala> Stream.exec(cats.effect.SyncIO(println("Hello"))).ifEmpty(Stream(1, 2, 3)).compile.toList.unsafeRunSync() res1: List[Int] = List(1, 2, 3)
Emits the supplied value if this stream finishes without emitting any elements. Note: fallback occurs any time stream evaluation finishes without emitting, even when effects have been evaluated.
Emits the supplied value if this stream finishes without emitting any elements. Note: fallback occurs any time stream evaluation finishes without emitting, even when effects have been evaluated.
- Example
scala> Stream.empty.ifEmptyEmit(0).toList res0: List[Int] = List(0)
Deterministically interleaves elements, starting on the left, terminating when the end of either branch is reached naturally.
Deterministically interleaves elements, starting on the left, terminating when the end of either branch is reached naturally.
- Example
scala> Stream(1, 2, 3).interleave(Stream(4, 5, 6, 7)).toList res0: List[Int] = List(1, 4, 2, 5, 3, 6)
Deterministically interleaves elements, starting on the left, terminating when the ends of both branches are reached naturally.
Deterministically interleaves elements, starting on the left, terminating when the ends of both branches are reached naturally.
- Example
scala> Stream(1, 2, 3).interleaveAll(Stream(4, 5, 6, 7)).toList res0: List[Int] = List(1, 4, 2, 5, 3, 6, 7)
Interrupts this stream after the specified duration has passed.
Interrupts this stream after the specified duration has passed.
Creates a scope that may be interrupted by calling scope#interrupt.
Creates a scope that may be interrupted by calling scope#interrupt.
Ties this stream to the given haltWhenTrue
stream.
The resulting stream performs all the effects and emits all the outputs
from this
stream (the fore), until the moment that the haltWhenTrue
stream ends, be it by emitting true
, error, or cancellation.
Ties this stream to the given haltWhenTrue
stream.
The resulting stream performs all the effects and emits all the outputs
from this
stream (the fore), until the moment that the haltWhenTrue
stream ends, be it by emitting true
, error, or cancellation.
The haltWhenTrue
stream is compiled and drained, asynchronously in the
background, until the moment it emits a value true
or raises an error.
This halts as soon as either branch halts.
If the haltWhenTrue
stream ends by raising an error, the resulting stream
rethrows that same error. If the haltWhenTrue
stream is cancelled, then
the resulting stream is interrupted (without cancellation).
Consider using the overload that takes a Signal
, Deferred
or F[Either[Throwable, Unit]]
.
Alias for interruptWhen(haltWhenTrue.discrete)
.
Alias for interruptWhen(haltWhenTrue.discrete)
.
Interrupts the stream, when haltOnSignal
finishes its evaluation.
Interrupts the stream, when haltOnSignal
finishes its evaluation.
Emits the specified separator between every pair of elements in the source stream.
Emits the specified separator between every pair of elements in the source stream.
- Example
scala> Stream(1, 2, 3, 4, 5).intersperse(0).toList res0: List[Int] = List(1, 0, 2, 0, 3, 0, 4, 0, 5)
This method preserves the Chunking structure of
this
stream.
Returns the last element of this stream, if non-empty.
Returns the last element of this stream, if non-empty.
- Example
scala> Stream(1, 2, 3).last.toList res0: List[Option[Int]] = List(Some(3))
Returns the last element of this stream, if non-empty, otherwise the supplied fallback
value.
Returns the last element of this stream, if non-empty, otherwise the supplied fallback
value.
- Example
scala> Stream(1, 2, 3).lastOr(0).toList res0: List[Int] = List(3) scala> Stream.empty.lastOr(0).toList res1: List[Int] = List(0)
Applies the specified pure function to each input and emits the result.
Applies the specified pure function to each input and emits the result.
- Example
scala> Stream("Hello", "World!").map(_.size).toList res0: List[Int] = List(5, 6)
Maps a running total according to S
and the input with the function f
.
Maps a running total according to S
and the input with the function f
.
- Example
scala> Stream("Hello", "World").mapAccumulate(0)((l, s) => (l + s.length, s.head)).toVector res0: Vector[(Int, Char)] = Vector((5,H), (10,W))
Alias for parEvalMap.
Alias for parEvalMap.
Alias for parEvalMapUnordered.
Alias for parEvalMapUnordered.
Applies the specified pure function to each chunk in this stream.
Applies the specified pure function to each chunk in this stream.
- Example
scala> Stream(1, 2, 3).append(Stream(4, 5, 6)).mapChunks { c => val ints = c.toArraySlice; for (i <- 0 until ints.values.size) ints.values(i) = 0; ints }.toList res0: List[Int] = List(0, 0, 0, 0, 0, 0)
Behaves like the identity function but halts the stream on an error and does not return the error.
Behaves like the identity function but halts the stream on an error and does not return the error.
- Example
scala> import cats.effect.SyncIO scala> (Stream(1,2,3) ++ Stream.raiseError[SyncIO](new RuntimeException) ++ Stream(4, 5, 6)).mask.compile.toList.unsafeRunSync() res0: List[Int] = List(1, 2, 3)
Interleaves the two inputs nondeterministically. The output stream
halts after BOTH s1
and s2
terminate normally, or in the event
of an uncaught failure on either s1
or s2
. Has the property that
merge(Stream.empty, s) == s
and merge(raiseError(e), s)
will
eventually terminate with raiseError(e)
, possibly after emitting some
elements of s
first.
Interleaves the two inputs nondeterministically. The output stream
halts after BOTH s1
and s2
terminate normally, or in the event
of an uncaught failure on either s1
or s2
. Has the property that
merge(Stream.empty, s) == s
and merge(raiseError(e), s)
will
eventually terminate with raiseError(e)
, possibly after emitting some
elements of s
first.
The implementation always tries to pull one chunk from each side before waiting for it to be consumed by resulting stream. As such, there may be up to two chunks (one from each stream) waiting to be processed while the resulting stream is processing elements.
Also note that if either side produces empty chunk, the processing on that side continues, w/o downstream requiring to consume result.
If either side does not emit anything (i.e. as result of drain) that side will continue to run even when the resulting stream did not ask for more data.
Note that even when this is equivalent to Stream(this, that).parJoinUnbounded
,
this implementation is little more efficient
- Example
scala> import scala.concurrent.duration._, cats.effect.IO, cats.effect.unsafe.implicits.global scala> val s1 = Stream.awakeEvery[IO](500.millis).scan(0)((acc, _) => acc + 1) scala> val s = s1.merge(Stream.sleep_[IO](250.millis) ++ s1) scala> s.take(6).compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 0, 1, 1, 2, 2)
Like merge
, but halts as soon as either branch halts.
Like merge
, but halts as soon as either branch halts.
Like merge
, but halts as soon as the s1
branch halts.
Like merge
, but halts as soon as the s1
branch halts.
Note: it is not guaranteed that the last element of the stream will come from s1
.
Like merge
, but halts as soon as the s2
branch halts.
Like merge
, but halts as soon as the s2
branch halts.
Note: it is not guaranteed that the last element of the stream will come from s2
.
Emits each output wrapped in a Some
and emits a None
at the end of the stream.
Emits each output wrapped in a Some
and emits a None
at the end of the stream.
s.noneTerminate.unNoneTerminate == s
- Example
scala> Stream(1,2,3).noneTerminate.toList res0: List[Option[Int]] = List(Some(1), Some(2), Some(3), None)
Run s2
after this
, regardless of errors during this
, then reraise any errors encountered during this
.
Run s2
after this
, regardless of errors during this
, then reraise any errors encountered during this
.
Note: this should not be used for resource cleanup! Use bracket
or onFinalize
instead.
- Example
scala> Stream(1, 2, 3).onComplete(Stream(4, 5)).toList res0: List[Int] = List(1, 2, 3, 4, 5)
Runs the supplied effectful action at the end of this stream, regardless of how the stream terminates.
Runs the supplied effectful action at the end of this stream, regardless of how the stream terminates.
Like onFinalize but provides the reason for finalization as an ExitCase[Throwable]
.
Like onFinalize but provides the reason for finalization as an ExitCase[Throwable]
.
Like onFinalizeCase but does not introduce a scope, allowing finalization to occur after subsequent appends or other scope-preserving transformations.
Like onFinalizeCase but does not introduce a scope, allowing finalization to occur after subsequent appends or other scope-preserving transformations.
Scopes can be manually introduced via scope if desired.
See onFinalizeWeak for more details on semantics.
Like onFinalize but does not introduce a scope, allowing finalization to occur after subsequent appends or other scope-preserving transformations.
Like onFinalize but does not introduce a scope, allowing finalization to occur after subsequent appends or other scope-preserving transformations.
Scopes can be manually introduced via scope if desired.
Example use case: a.concurrently(b).onFinalizeWeak(f).compile.resource.use(g)
In this example, use of onFinalize
would result in b
shutting down before
g
is run, because onFinalize
creates a scope, whose lifetime is extended
over the compiled resource. By using onFinalizeWeak
instead, f
is attached
to the scope governing concurrently
.
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results
downstream in the same order as the input stream. The number of concurrent effects
is limited by the maxConcurrent
parameter.
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results
downstream in the same order as the input stream. The number of concurrent effects
is limited by the maxConcurrent
parameter.
See Stream#parEvalMapUnordered if there is no requirement to retain the order of the original stream.
- Example
scala> import cats.effect.IO, cats.effect.unsafe.implicits.global scala> Stream(1,2,3,4).covary[IO].parEvalMap(2)(i => IO(println(i))).compile.drain.unsafeRunSync() res0: Unit = ()
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results
downstream. The number of concurrent effects is limited by the maxConcurrent
parameter.
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results
downstream. The number of concurrent effects is limited by the maxConcurrent
parameter.
See Stream#parEvalMap if retaining the original order of the stream is required.
- Example
scala> import cats.effect.IO, cats.effect.unsafe.implicits.global scala> Stream(1,2,3,4).covary[IO].parEvalMapUnordered(2)(i => IO(println(i))).compile.drain.unsafeRunSync() res0: Unit = ()
Concurrent zip.
Concurrent zip.
It combines elements pairwise and in order like zip
, but
instead of pulling from the left stream and then from the right
stream, it evaluates both pulls concurrently.
The resulting stream terminates when either stream terminates.
The concurrency is bounded following a model of successive races: both sides start evaluation of a single element concurrently, and whichever finishes first waits for the other to catch up and the resulting pair to be emitted, at which point the process repeats. This means that no branch is allowed to get ahead by more than one element.
Notes:
- Effects within each stream are executed in order, they are only concurrent with respect to each other.
- The output of
parZip
is guaranteed to be the same aszip
, although the order in which effects are executed differs.
Like parZip
, but combines elements pairwise with a function instead
of tupling them.
Like parZip
, but combines elements pairwise with a function instead
of tupling them.
Pause this stream when pauseWhenTrue
emits true
, resuming when false
is emitted.
Pause this stream when pauseWhenTrue
emits true
, resuming when false
is emitted.
Pause this stream when pauseWhenTrue
is true
, resume when it's false
.
Pause this stream when pauseWhenTrue
is true
, resume when it's false
.
Behaves like identity
, but starts fetches up to n
chunks in parallel with downstream
consumption, enabling processing on either side of the prefetchN
to run in parallel.
Behaves like identity
, but starts fetches up to n
chunks in parallel with downstream
consumption, enabling processing on either side of the prefetchN
to run in parallel.
Prints each element of this stream to standard out, converting each element to a String
via Show
.
Prints each element of this stream to standard out, converting each element to a String
via Show
.
Rechunks the stream such that output chunks are within [inputChunk.size * minFactor, inputChunk.size * maxFactor].
Rechunks the stream such that output chunks are within [inputChunk.size * minFactor, inputChunk.size * maxFactor].
Rechunks the stream such that output chunks are within [inputChunk.size * minFactor, inputChunk.size * maxFactor]
.
The pseudo random generator is deterministic based on the supplied seed.
Rechunks the stream such that output chunks are within [inputChunk.size * minFactor, inputChunk.size * maxFactor]
.
The pseudo random generator is deterministic based on the supplied seed.
Reduces this stream with the Semigroup for O
.
Reduces this stream with the Semigroup for O
.
- Example
scala> Stream("The", "quick", "brown", "fox").intersperse(" ").reduceSemigroup.toList res0: List[String] = List(The quick brown fox)
Repartitions the input with the function f
. On each step f
is applied
to the input and all elements but the last of the resulting sequence
are emitted. The last element is then appended to the next input using the
Semigroup S
.
Repartitions the input with the function f
. On each step f
is applied
to the input and all elements but the last of the resulting sequence
are emitted. The last element is then appended to the next input using the
Semigroup S
.
- Example
scala> Stream("Hel", "l", "o Wor", "ld").repartition(s => Chunk.array(s.split(" "))).toList res0: List[String] = List(Hello, World)
Repeat this stream an infinite number of times.
Repeat this stream an infinite number of times.
s.repeat == s ++ s ++ s ++ ...
- Example
scala> Stream(1,2,3).repeat.take(8).toList res0: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2)
Repeat this stream a given number of times.
Repeat this stream a given number of times.
s.repeatN(n) == s ++ s ++ s ++ ... (n times)
- Example
scala> Stream(1,2,3).repeatN(3).take(100).toList res0: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)
Converts a Stream[F,Either[Throwable,O]]
to a Stream[F,O]
, which emits right values and fails upon the first Left(t)
.
Preserves chunkiness.
Converts a Stream[F,Either[Throwable,O]]
to a Stream[F,O]
, which emits right values and fails upon the first Left(t)
.
Preserves chunkiness.
- Example
scala> import cats.effect.SyncIO scala> Stream(Right(1), Right(2), Left(new RuntimeException), Right(3)).rethrow[SyncIO, Int].handleErrorWith(_ => Stream(-1)).compile.toList.unsafeRunSync() res0: List[Int] = List(-1)
Left fold which outputs all intermediate results.
Left fold which outputs all intermediate results.
- Example
scala> Stream(1,2,3,4).scan(0)(_ + _).toList res0: List[Int] = List(0, 1, 3, 6, 10)
More generally:
Stream().scan(z)(f) == Stream(z)
Stream(x1).scan(z)(f) == Stream(z, f(z,x1))
Stream(x1,x2).scan(z)(f) == Stream(z, f(z,x1), f(f(z,x1),x2))
etc
Like [[scan]]
, but uses the first element of the stream as the seed.
Like [[scan]]
, but uses the first element of the stream as the seed.
- Example
scala> Stream(1,2,3,4).scan1(_ + _).toList res0: List[Int] = List(1, 3, 6, 10)
Like scan
but f
is applied to each chunk of the source stream.
The resulting chunk is emitted while the resulting state is used in the
next invocation of f
.
Like scan
but f
is applied to each chunk of the source stream.
The resulting chunk is emitted while the resulting state is used in the
next invocation of f
.
Many stateful pipes can be implemented efficiently (i.e., supporting fusion) with this method.
More general version of scanChunks
where the current state (i.e., S
) can be inspected
to determine if another chunk should be pulled or if the stream should terminate.
Termination is signaled by returning None
from f
. Otherwise, a function which consumes
the next chunk is returned wrapped in Some
.
More general version of scanChunks
where the current state (i.e., S
) can be inspected
to determine if another chunk should be pulled or if the stream should terminate.
Termination is signaled by returning None
from f
. Otherwise, a function which consumes
the next chunk is returned wrapped in Some
.
- Example
scala> def take[F[_],O](s: Stream[F,O], n: Int): Stream[F,O] = | s.scanChunksOpt(n) { n => if (n <= 0) None else Some((c: Chunk[O]) => if (c.size < n) (n - c.size, c) else (0, c.take(n))) } scala> take(Stream.range(0,100), 5).toList res0: List[Int] = List(0, 1, 2, 3, 4)
Alias for map(f).scanMonoid
.
Alias for map(f).scanMonoid
.
- Example
scala> Stream("a", "aa", "aaa", "aaaa").scanMap(_.length).toList res0: List[Int] = List(0, 1, 3, 6, 10)
Folds this stream with the monoid for O
while emitting all intermediate results.
Folds this stream with the monoid for O
while emitting all intermediate results.
- Example
scala> Stream(1, 2, 3, 4).scanMonoid.toList res0: List[Int] = List(0, 1, 3, 6, 10)
Introduces an explicit scope.
Introduces an explicit scope.
Scopes are normally introduced automatically, when using bracket
or similar
operations that acquire resources and run finalizers. Manual scope introduction
is useful when using onFinalizeWeak/onFinalizeCaseWeak, where no scope
is introduced.
Groups inputs in fixed size chunks by passing a "sliding window"
of size n
over them. If the input contains less than or equal to
n
elements, only one chunk of this size will be emitted.
Groups inputs in fixed size chunks by passing a "sliding window"
of size n
over them. If the input contains less than or equal to
n
elements, only one chunk of this size will be emitted.
- Throws
- scala.IllegalArgumentException
if
n
<= 0
- Example
scala> Stream(1, 2, 3, 4).sliding(2).toList res0: List[fs2.Chunk[Int]] = List(Chunk(1, 2), Chunk(2, 3), Chunk(3, 4))
Groups inputs in fixed size chunks by passing a "sliding window"
of size with step over them. If the input contains less than or equal to
size
elements, only one chunk of this size will be emitted.
Groups inputs in fixed size chunks by passing a "sliding window"
of size with step over them. If the input contains less than or equal to
size
elements, only one chunk of this size will be emitted.
- Throws
- scala.IllegalArgumentException
if
size
<= 0 |step
<= 0
- Example
scala> Stream(1, 2, 3, 4, 5).sliding(2, 3).toList res0: List[fs2.Chunk[Int]] = List(Chunk(1, 2), Chunk(4, 5)) scala> Stream(1, 2, 3, 4, 5).sliding(3, 2).toList res1: List[fs2.Chunk[Int]] = List(Chunk(1, 2, 3), Chunk(3, 4, 5))
Starts this stream and cancels it as finalization of the returned stream.
Starts this stream and cancels it as finalization of the returned stream.
Breaks the input into chunks where the delimiter matches the predicate. The delimiter does not appear in the output. Two adjacent delimiters in the input result in an empty chunk in the output.
Breaks the input into chunks where the delimiter matches the predicate. The delimiter does not appear in the output. Two adjacent delimiters in the input result in an empty chunk in the output.
- Example
scala> Stream.range(0, 10).split(_ % 4 == 0).toList res0: List[Chunk[Int]] = List(empty, Chunk(1, 2, 3), Chunk(5, 6, 7), Chunk(9))
Like Stream.flatMap but interrupts the inner stream when new elements arrive in the outer stream.
Like Stream.flatMap but interrupts the inner stream when new elements arrive in the outer stream.
The implementation will try to preserve chunks like Stream.merge.
Finializers of each inner stream are guaranteed to run before the next inner stream starts.
When the outer stream stops gracefully, the currently running inner stream will continue to run.
When an inner stream terminates/interrupts, nothing happens until the next element arrives in the outer stream(i.e the outer stream holds the stream open during this time or else the stream terminates)
When either the inner or outer stream fails, the entire stream fails and the finalizer of the inner stream runs before the outer one.
Emits all elements of the input except the first one.
Emits all elements of the input except the first one.
- Example
scala> Stream(1,2,3).tail.toList res0: List[Int] = List(2, 3)
Emits the first n
elements of this stream.
Emits the first n
elements of this stream.
- Example
scala> Stream.range(0,1000).take(5).toList res0: List[Int] = List(0, 1, 2, 3, 4)
Emits the last n
elements of the input.
Emits the last n
elements of the input.
- Example
scala> Stream.range(0,1000).takeRight(5).toList res0: List[Int] = List(995, 996, 997, 998, 999)
Emits the longest prefix of the input for which all elements test true according to f
.
Emits the longest prefix of the input for which all elements test true according to f
.
- Example
scala> Stream.range(0,1000).takeWhile(_ != 5).toList res0: List[Int] = List(0, 1, 2, 3, 4)
Transforms this stream using the given Pipe
.
Transforms this stream using the given Pipe
.
- Example
scala> Stream("Hello", "world").through(text.utf8.encode).toVector.toArray res0: Array[Byte] = Array(72, 101, 108, 108, 111, 119, 111, 114, 108, 100)
Transforms this stream and s2
using the given Pipe2
.
Transforms this stream and s2
using the given Pipe2
.
Fails this stream with a TimeoutException if it does not complete within given timeout
.
Fails this stream with a TimeoutException if it does not complete within given timeout
.
Translates effect type from F
to G
using the supplied FunctionK
.
Translates effect type from F
to G
using the supplied FunctionK
.
Converts the input to a stream of 1-element chunks.
Converts the input to a stream of 1-element chunks.
- Example
scala> (Stream(1,2,3) ++ Stream(4,5,6)).unchunk.chunks.toList res0: List[Chunk[Int]] = List(Chunk(1), Chunk(2), Chunk(3), Chunk(4), Chunk(5), Chunk(6))
Determinsitically zips elements, terminating when the end of either branch is reached naturally.
Determinsitically zips elements, terminating when the end of either branch is reached naturally.
- Example
scala> Stream(1, 2, 3).zip(Stream(4, 5, 6, 7)).toList res0: List[(Int,Int)] = List((1,4), (2,5), (3,6))
Determinsitically zips elements, terminating when the ends of both branches
are reached naturally, padding the left branch with pad1
and padding the right branch
with pad2
as necessary.
Determinsitically zips elements, terminating when the ends of both branches
are reached naturally, padding the left branch with pad1
and padding the right branch
with pad2
as necessary.
- Example
scala> Stream(1,2,3).zipAll(Stream(4,5,6,7))(0,0).toList res0: List[(Int,Int)] = List((1,4), (2,5), (3,6), (0,7))
Determinsitically zips elements with the specified function, terminating
when the ends of both branches are reached naturally, padding the left
branch with pad1
and padding the right branch with pad2
as necessary.
Determinsitically zips elements with the specified function, terminating
when the ends of both branches are reached naturally, padding the left
branch with pad1
and padding the right branch with pad2
as necessary.
- Example
scala> Stream(1,2,3).zipAllWith(Stream(4,5,6,7))(0, 0)(_ + _).toList res0: List[Int] = List(5, 7, 9, 7)
Like zip
, but selects the left values only.
Useful with timed streams, the example below will emit a number every 100 milliseconds.
Like zip
, but selects the left values only.
Useful with timed streams, the example below will emit a number every 100 milliseconds.
- Example
scala> import scala.concurrent.duration._, cats.effect.IO, cats.effect.unsafe.implicits.global scala> val s = Stream.range(0, 5) zipLeft Stream.fixedDelay[IO](100.millis) scala> s.compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 2, 3, 4)
Like zip
, but selects the right values only.
Useful with timed streams, the example below will emit a number every 100 milliseconds.
Like zip
, but selects the right values only.
Useful with timed streams, the example below will emit a number every 100 milliseconds.
- Example
scala> import scala.concurrent.duration._, cats.effect.IO, cats.effect.unsafe.implicits.global scala> val s = Stream.fixedDelay[IO](100.millis) zipRight Stream.range(0, 5) scala> s.compile.toVector.unsafeRunSync() res0: Vector[Int] = Vector(0, 1, 2, 3, 4)
Determinsitically zips elements using the specified function, terminating when the end of either branch is reached naturally.
Determinsitically zips elements using the specified function, terminating when the end of either branch is reached naturally.
- Example
scala> Stream(1, 2, 3).zipWith(Stream(4, 5, 6, 7))(_ + _).toList res0: List[Int] = List(5, 7, 9)
Zips the elements of the input stream with its indices, and returns the new stream.
Zips the elements of the input stream with its indices, and returns the new stream.
- Example
scala> Stream("The", "quick", "brown", "fox").zipWithIndex.toList res0: List[(String,Long)] = List((The,0), (quick,1), (brown,2), (fox,3))
Zips each element of this stream with the next element wrapped into Some
.
The last element is zipped with None
.
Zips each element of this stream with the next element wrapped into Some
.
The last element is zipped with None
.
- Example
scala> Stream("The", "quick", "brown", "fox").zipWithNext.toList res0: List[(String,Option[String])] = List((The,Some(quick)), (quick,Some(brown)), (brown,Some(fox)), (fox,None))
Zips each element of this stream with the previous element wrapped into Some
.
The first element is zipped with None
.
Zips each element of this stream with the previous element wrapped into Some
.
The first element is zipped with None
.
- Example
scala> Stream("The", "quick", "brown", "fox").zipWithPrevious.toList res0: List[(Option[String],String)] = List((None,The), (Some(The),quick), (Some(quick),brown), (Some(brown),fox))
Zips each element of this stream with its previous and next element wrapped into Some
.
The first element is zipped with None
as the previous element,
the last element is zipped with None
as the next element.
Zips each element of this stream with its previous and next element wrapped into Some
.
The first element is zipped with None
as the previous element,
the last element is zipped with None
as the next element.
- Example
scala> Stream("The", "quick", "brown", "fox").zipWithPreviousAndNext.toList res0: List[(Option[String],String,Option[String])] = List((None,The,Some(quick)), (Some(The),quick,Some(brown)), (Some(quick),brown,Some(fox)), (Some(brown),fox,None))
Zips the input with a running total according to S
, up to but not including the current element. Thus the initial
z
value is the first emitted to the output:
Zips the input with a running total according to S
, up to but not including the current element. Thus the initial
z
value is the first emitted to the output:
- See also
- Example
scala> Stream("uno", "dos", "tres", "cuatro").zipWithScan(0)(_ + _.length).toList res0: List[(String,Int)] = List((uno,0), (dos,3), (tres,6), (cuatro,10))
Zips the input with a running total according to S
, including the current element. Thus the initial
z
value is the first emitted to the output:
Zips the input with a running total according to S
, including the current element. Thus the initial
z
value is the first emitted to the output:
- See also
- Example
scala> Stream("uno", "dos", "tres", "cuatro").zipWithScan1(0)(_ + _.length).toList res0: List[(String, Int)] = List((uno,3), (dos,6), (tres,10), (cuatro,16))