如何将 `List[IO[Unit]]` 转换为 `Stream[IO,Unit]`
How to convert a `List[IO[Unit]]` into `Stream[IO,Unit]`
我有一个 List[IO[Unit]]
,它由 IO
编码的不同作品组成。我想把它转换成 Stream[IO,Unit]
目前我做的是这样的
val works: List[IO[Unit]]
works.map(work => Stream.eval(work)).reduceLeft((left, right) => left ++ right)
有没有更好的方法?
我能想到这三个备选方案:
(注意,我只是检查了它们的类型检查,但我没有 运行 它们)
def stream1: Stream[IO, Unit] =
Stream.evalSeq(works.sequence)
def stream2: Stream[IO, Unit] =
Stream.evals(works.sequence)
def stream3: Stream[IO, Unit] =
Stream.unfoldEval(works) {
case work :: tail =>
work.map { io =>
Some(io -> tail)
}
case Nil =>
IO.pure(None)
}
顺便说一句,如果你在 map
.
之后得到 List[IO[Unit]]
您可以 data.traverse(f)
而不是 works.map(f).sequence
并且 f(input).map { io =>
而不是 work.map { io =>
我建议做其中之一:
Stream.emits(works).flatMap(Stream.eval) // or
Stream.emits(works).evalMap(x => x) // which is the same, or
Stream(works: _*).evalMap(x => x) // which is also the same
与在 works.sequence
上执行 Stream.evals
的区别在于您失去了效果由不同部分组成的事实。如果您 运行 部分流式传输,这将自行浮出水面,例如通过做:
stream.take(3).compile.drain
如果您不序列,它只会运行来自works
的前3个元素。如果这样做,它将 运行 所有这些。
从 Luis Miguel 提出的其他选项中,只有 unfoldEval
保留了分隔,但这可能有点矫枉过正。
我有一个 List[IO[Unit]]
,它由 IO
编码的不同作品组成。我想把它转换成 Stream[IO,Unit]
目前我做的是这样的
val works: List[IO[Unit]]
works.map(work => Stream.eval(work)).reduceLeft((left, right) => left ++ right)
有没有更好的方法?
我能想到这三个备选方案:
(注意,我只是检查了它们的类型检查,但我没有 运行 它们)
def stream1: Stream[IO, Unit] =
Stream.evalSeq(works.sequence)
def stream2: Stream[IO, Unit] =
Stream.evals(works.sequence)
def stream3: Stream[IO, Unit] =
Stream.unfoldEval(works) {
case work :: tail =>
work.map { io =>
Some(io -> tail)
}
case Nil =>
IO.pure(None)
}
顺便说一句,如果你在 map
.
您可以 data.traverse(f)
而不是 works.map(f).sequence
并且 f(input).map { io =>
而不是 work.map { io =>
我建议做其中之一:
Stream.emits(works).flatMap(Stream.eval) // or
Stream.emits(works).evalMap(x => x) // which is the same, or
Stream(works: _*).evalMap(x => x) // which is also the same
与在 works.sequence
上执行 Stream.evals
的区别在于您失去了效果由不同部分组成的事实。如果您 运行 部分流式传输,这将自行浮出水面,例如通过做:
stream.take(3).compile.drain
如果您不序列,它只会运行来自works
的前3个元素。如果这样做,它将 运行 所有这些。
从 Luis Miguel 提出的其他选项中,只有 unfoldEval
保留了分隔,但这可能有点矫枉过正。