Appends s2
to the end of this stream.
Alias for flatMap(_ => s2)
.
Appends s2
to the end of this stream.
Appends s2
to the end of this stream. Alias for s1 ++ s2
.
Alias for covary, to be able to write Stream.empty[X]
.
Alias for covary, to be able to write Stream.empty[X]
.
Alias for _.map(_ => o2)
.
Alias for _.map(_ => o2)
.
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
.
scala> (Stream(1,2,3) ++ Stream.raiseError(new RuntimeException) ++ Stream(4,5,6)).attempt.toList 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.
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.
scala> import cats.effect.IO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 100).covary[IO]. | evalMap(i => IO { buf += s">$i"; i }). | buffer(4). | evalMap(i => IO { 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.
scala> import cats.effect.IO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 10).covary[IO]. | evalMap(i => IO { buf += s">$i"; i }). | bufferAll. | evalMap(i => IO { 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.
scala> import cats.effect.IO scala> val buf = new scala.collection.mutable.ListBuffer[String]() scala> Stream.range(0, 10).covary[IO]. | evalMap(i => IO { buf += s">$i"; i }). | bufferBy(_ % 2 == 0). | evalMap(i => IO { 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.
scala> import cats.implicits._ 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)
scala> import cats.implicits._ scala> Stream(1,1,2,4,6,9).changesBy(_ % 2).toList res0: List[Int] = List(1, 2, 9)
Outputs chunk with a limited maximum size, splitting as necessary.
Outputs chunk with a limited maximum size, splitting as necessary.
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 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.
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.
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.
Filters and maps simultaneously. Calls collect
on each chunk in the stream.
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.
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.
scala> import cats.effect.IO scala> val prg: IO[Vector[Int]] = Stream.eval(IO(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 similar to this mergeHaltL that.drain
but ensures the that.drain
stream continues
to be evaluated regardless of how this
is evaluated or how the resulting stream is processed.
This method is also similar to Stream(this,that).parJoin(2)
but terminates that
upon termination of
this
.
scala> import cats.effect.IO, scala.concurrent.ExecutionContext.Implicits.global scala> val data: Stream[IO,Int] = Stream.range(1, 10).covary[IO] scala> Stream.eval(async.signalOf[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.
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.
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.
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 type.
Lifts this stream to the specified effect type.
Lifts this stream to the specified effect and output types.
Lifts this stream to the specified effect and output types.
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.
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.
scala> import scala.concurrent.duration._, scala.concurrent.ExecutionContext.Implicits.global, cats.effect.IO 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)
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.
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.
scala> import cats.effect.IO scala> Stream.eval(IO(println("x"))).drain.compile.toVector.unsafeRunSync res0: Vector[Nothing] = Vector()
Drops n
elements of the input, then echoes the rest.
Drops n
elements of the input, then echoes the rest.
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.
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.
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.
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.
scala> Stream.range(0,10).dropThrough(_ != 4).toList res0: List[Int] = List(5, 6, 7, 8, 9)
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.
scala> Stream.range(0,10).dropWhile(_ != 4).toList res0: List[Int] = List(4, 5, 6, 7, 8, 9)
Like merge
, but tags each output with the branch it came from.
Like merge
, but tags each output with the branch it came from.
scala> import scala.concurrent.duration._, scala.concurrent.ExecutionContext.Implicits.global, cats.effect.IO scala> val s1 = Stream.awakeEvery[IO](1000.millis).scan(0)((acc, i) => 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))
Alias for flatMap(o => Stream.eval(f(o)))
.
Alias for flatMap(o => Stream.eval(f(o)))
.
scala> import cats.effect.IO scala> Stream(1,2,3,4).evalMap(i => IO(println(i))).compile.drain.unsafeRunSync res0: Unit = ()
Like Stream#mapAccumulate
, but accepts a function returning an F[_]
.
Like Stream#mapAccumulate
, but accepts a function returning an F[_]
.
scala> import cats.effect.IO scala> Stream(1,2,3,4).covary[IO].evalMapAccumulate(0)((acc,i) => IO((i, acc + i))).compile.toVector.unsafeRunSync res0: Vector[(Int, Int)] = Vector((1,1), (2,3), (3,5), (4,7))
Like Stream#scan
, but accepts a function returning an F[_]
.
Like Stream#scan
, but accepts a function returning an F[_]
.
scala> import cats.effect.IO scala> Stream(1,2,3,4).covary[IO].evalScan(0)((acc,i) => IO(acc + i)).compile.toVector.unsafeRunSync res0: Vector[Int] = Vector(0, 1, 3, 6, 10)
Like observe
but observes with a function O => F[Unit]
instead of a sink.
Like observe
but observes with a function O => F[Unit]
instead of a sink.
Not as powerful as observe
since not all sinks can be represented by O => F[Unit]
, 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.
Emits true
as soon as a matching element is received, else false
if no input matches.
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.
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.
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.
scala> Stream.range(1,10).find(_ % 2 == 0).toList res0: List[Int] = List(2)
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.
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.
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.
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.
Folds all inputs using the supplied binary operator, and emits a single-element stream, or the empty stream if the input is empty.
scala> Stream(1, 2, 3, 4, 5).fold1(_ + _).toList res0: List[Int] = List(15)
Alias for map(f).foldMonoid
.
Alias for map(f).foldMonoid
.
scala> import cats.implicits._ 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
.
scala> import cats.implicits._ scala> Stream(1, 2, 3, 4, 5).foldMonoid.toList res0: List[Int] = List(15)
Emits a single true
value if all input matches the predicate.
Emits a single true
value if all input matches the predicate.
Halts with false
as soon as a non-matching element is received.
scala> Stream(1, 2, 3, 4, 5).forall(_ < 10).toList res0: List[Boolean] = List(true)
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.
scala> import cats.implicits._ 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)))
If this
terminates with Stream.raiseError(e)
, invoke h(e)
.
If this
terminates with Stream.raiseError(e)
, invoke h(e)
.
scala> Stream(1, 2, 3).append(Stream.raiseError(new RuntimeException)).handleErrorWith(t => Stream(0)).toList 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.
scala> Stream(1, 2, 3).head.toList res0: List[Int] = List(1)
Determinsitically interleaves elements, starting on the left, terminating when the end of either branch is reached naturally.
Determinsitically interleaves elements, starting on the left, terminating when the end of either branch is reached naturally.
scala> Stream(1, 2, 3).interleave(Stream(4, 5, 6, 7)).toList res0: List[Int] = List(1, 4, 2, 5, 3, 6)
Determinsitically interleaves elements, starting on the left, terminating when the ends of both branches are reached naturally.
Determinsitically interleaves elements, starting on the left, terminating when the ends of both branches are reached naturally.
scala> Stream(1, 2, 3).interleaveAll(Stream(4, 5, 6, 7)).toList res0: List[Int] = List(1, 4, 2, 5, 3, 6, 7)
Creates a scope that may be interrupted by calling scope#interrupt.
Interrupts the stream, when haltOnSignal
finishes its evaluation.
Alias for interruptWhen(haltWhenTrue.discrete)
.
Let through the s2
branch as long as the s1
branch is false
,
listening asynchronously for the left branch to become true
.
Let through the s2
branch as long as the s1
branch is false
,
listening asynchronously for the left branch to become true
.
This halts as soon as either branch halts.
Consider using the overload that takes a Signal
.
Caution: interruption is checked as elements are pulled from the returned stream. As a result,
streams which stop pulling from the returned stream end up uninterruptible. For example,
s.interruptWhen(s2).flatMap(_ => infiniteStream)
will not be interrupted when s2
is true
because s1.interruptWhen(s2)
is never pulled for another element after the first element has been
emitted. To fix, consider s.flatMap(_ => infiniteStream).interruptWhen(s2)
.
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.
scala> Stream(1, 2, 3, 4, 5).intersperse(0).toList res0: List[Int] = List(1, 0, 2, 0, 3, 0, 4, 0, 5)
Returns the last element of this stream, if non-empty.
Returns the last element of this stream, if non-empty.
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.
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.
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
.
scala> Stream("Hello", "World").mapAccumulate(0)((l, s) => (l + s.length, s.head)).toVector res0: Vector[(Int, Char)] = Vector((5,H), (10,W))
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results downstream in the same order as the input stream.
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 parallelism
parameter.
See Stream#mapAsyncUnordered if there is no requirement to retain the order of the original stream.
scala> import cats.effect.IO, scala.concurrent.ExecutionContext.Implicits.global scala> Stream(1,2,3,4).covary[IO].mapAsync(2)(i => IO(println(i))).compile.drain.unsafeRunSync res0: Unit = ()
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results downstream.
Like Stream#evalMap, but will evaluate effects in parallel, emitting the results
downstream. The number of concurrent effects is limited by the parallelism
parameter.
See Stream#mapAsync if retaining the original order of the stream is required.
scala> import cats.effect.IO, scala.concurrent.ExecutionContext.Implicits.global scala> Stream(1,2,3,4).covary[IO].mapAsyncUnordered(2)(i => IO(println(i))).compile.drain.unsafeRunSync res0: Unit = ()
Applies the specified pure function to each chunk in this stream.
Applies the specified pure function to each chunk in this stream.
scala> Stream(1, 2, 3).append(Stream(4, 5, 6)).mapChunks { c => val ints = c.toInts; 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.
scala> (Stream(1,2,3) ++ Stream.raiseError(new RuntimeException) ++ Stream(4, 5, 6)).mask.toList res0: List[Int] = List(1, 2, 3)
Interleaves the two inputs nondeterministically.
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 s1.merge(s2.drain) == s1.concurrently(s2)
, the concurrently
alternative is
more efficient.
scala> import scala.concurrent.duration._, scala.concurrent.ExecutionContext.Implicits.global, cats.effect.IO scala> val s1 = Stream.awakeEvery[IO](500.millis).scan(0)((acc, i) => 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 the s1
branch halts.
Like merge
, but halts as soon as the s2
branch halts.
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
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.
scala> Stream(1, 2, 3).onComplete(Stream(4, 5)).toList res0: List[Int] = List(1, 2, 3, 4, 5)
Run the supplied effectful action at the end of this stream, regardless of how the stream terminates.
Nondeterministically merges a stream of streams (outer
) in to a single stream,
opening at most maxOpen
streams at any point in time.
Nondeterministically merges a stream of streams (outer
) in to a single stream,
opening at most maxOpen
streams at any point in time.
The outer stream is evaluated and each resulting inner stream is run concurrently,
up to maxOpen
stream. Once this limit is reached, evaluation of the outer stream
is paused until one or more inner streams finish evaluating.
When the outer stream stops gracefully, all inner streams continue to run, resulting in a stream that will stop when all inner streams finish their evaluation.
When the outer stream fails, evaluation of all inner streams is interrupted and the resulting stream will fail with same failure.
When any of the inner streams fail, then the outer stream and all other inner streams are interrupted, resulting in stream that fails with the error of the stream that caused initial failure.
Finalizers on each inner stream are run at the end of the inner stream, concurrently with other stream computations.
Finalizers on the outer stream are run after all inner streams have been pulled from the outer stream but not before all inner streams terminate -- hence finalizers on the outer stream will run AFTER the LAST finalizer on the very last inner stream.
Finalizers on the returned stream are run after the outer stream has finished and all open inner streams have finished.
Maximum number of open inner streams at any time. Must be > 0.
Like parJoin but races all inner streams simultaneously.
Alias for pauseWhen(pauseWhenTrue.discrete)
.
Like interrupt
but resumes the stream when left branch goes to true.
Alias for prefetchN(1)
.
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.
Alias for fold1.
Reduces this stream with the Semigroup for O
.
Reduces this stream with the Semigroup for O
.
scala> import cats.implicits._ scala> Stream("The", "quick", "brown", "fox").intersperse(" ").reduceSemigroup.toList res0: List[String] = List(The quick brown fox)
Repartitions the input with the function f
.
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
.
scala> import cats.implicits._ 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 ++ ...
scala> Stream(1,2,3).repeat.take(8).toList res0: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2)
Converts a Stream[F,Either[Throwable,O]]
to a Stream[F,O]
, which emits right values and fails upon the first Left(t)
.
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.
scala> Stream(Right(1), Right(2), Left(new RuntimeException), Right(3)).rethrow.handleErrorWith(t => Stream(-1)).toList res0: List[Int] = List(-1)
Left fold which outputs all intermediate results.
Left fold which outputs all intermediate results.
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.
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.
Like scan
but f
is applied to each chunk of the source stream.
The resulting chunk is emitted and the result of the chunk 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.
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
.
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 => 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)
Scopes are typically inserted automatically, at the boundary of a pull (i.e., when a pull is converted to a stream).
Scopes are typically inserted automatically, at the boundary of a pull (i.e., when a pull
is converted to a stream). This method allows a scope to be explicitly demarcated so that
resources can be freed earlier than when using automatically inserted scopes. This is
useful when using streamNoScope
to convert from Pull
to Stream
-- i.e., by choosing
to *not* have scopes inserted automatically, you may end up needing to demarcate scopes
manually at a higher level in the stream structure.
Note: see the disclaimer about the use of streamNoScope
.
Groups inputs in fixed size chunks by passing a "sliding window"
of size n
over them.
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.
scala> Stream(1, 2, 3, 4).sliding(2).toList res0: List[scala.collection.immutable.Queue[Int]] = List(Queue(1, 2), Queue(2, 3), Queue(3, 4))
scala.IllegalArgumentException
if n
<= 0
Breaks the input into chunks where the delimiter matches the predicate.
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.
scala> Stream.range(0, 10).split(_ % 4 == 0).toList res0: List[Chunk[Int]] = List(Chunk(), Chunk(1, 2, 3), Chunk(5, 6, 7), Chunk(9))
Emits all elements of the input except the first one.
Emits all elements of the input except the first one.
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.
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.
scala> Stream.range(0,1000).takeRight(5).toList res0: List[Int] = List(995, 996, 997, 998, 999)
Like takeWhile, but emits the first value which tests false.
Like takeWhile, but emits the first value which tests false.
scala> Stream.range(0,1000).takeThrough(_ != 5).toList res0: List[Int] = List(0, 1, 2, 3, 4, 5)
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
.
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
.
scala> Stream("Hello", "world").through(text.utf8Encode).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
.
Runs this pure stream and returns the emitted elements in a collection of the specified type.
Runs this pure stream and returns the emitted elements in a collection of the specified type. Note: this method is only available on pure streams.
Applies the given sink to this stream.
Applies the given sink to this stream.
scala> import cats.effect.IO, cats.implicits._ scala> Stream(1,2,3).covary[IO].to(Sink.showLinesStdOut).compile.drain.unsafeRunSync res0: Unit = ()
Runs this pure stream and returns the emitted elements in a list.
Runs this pure stream and returns the emitted elements in a list. Note: this method is only available on pure streams.
Runs this pure stream and returns the emitted elements in a vector.
Runs this pure stream and returns the emitted elements in a vector. Note: this method is only available on pure streams.
Translates effect type from F
to G
using the supplied FunctionK
.
Filters any 'None'.
Filters any 'None'.
scala> Stream(Some(1), Some(2), None, Some(3), None).unNone.toList res0: List[Int] = List(1, 2, 3)
Halts the input stream at the first None
.
Halts the input stream at the first None
.
scala> Stream(Some(1), Some(2), None, Some(3), None).unNoneTerminate.toList res0: List[Int] = List(1, 2)
Converts the input to a stream of 1-element chunks.
Converts the input to a stream of 1-element chunks.
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.
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.
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.
scala> Stream(1,2,3).zipAllWith(Stream(4,5,6,7))(0, 0)(_ + _).toList res0: List[Int] = List(5, 7, 9, 7)
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.
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.
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
.
Zips each element of this stream with the next element wrapped into Some
.
The last element is zipped with None
.
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
.
Zips each element of this stream with the previous element wrapped into Some
.
The first element is zipped with None
.
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
.
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.
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.
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:
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.
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:
scala> Stream("uno", "dos", "tres", "cuatro").zipWithScan1(0)(_ + _.length).toList res0: List[(String, Int)] = List((uno,3), (dos,6), (tres,10), (cuatro,16))
A stream producing output of type
O
and which may evaluateF
effects. IfF
is Pure, the stream evaluates no effects.Laws (using infix syntax):
append
forms a monoid in conjunction withempty
: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 byhandleErrorWith
: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 withemit
andflatMap
: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 gThe 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
ifff(a)
is identical tof(b)
for allf
)normalize(s)
can be defined ass.flatMap(Stream.emit)
, which just produces a singly-chunked stream from any input streams
.Note: For efficiency
Stream.map
function operates on an entire chunk at a time and preserves chunk structure, which differs from themap
derived from the monad (s map f == s flatMap (f andThen Stream.emit)
) which would produce singleton chunk. In particular, iff
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.