我有一个List[IO[Unit]]
由IO
. 我想把它转换成Stream[IO,Unit]
目前,我所做的是这个
val works: List[IO[Unit]]
works.map(work => Stream.eval(work)).reduceLeft((left, right) => left ++ right)
有没有更好的办法?
我有一个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
Andf(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
与Stream.evals
在 a 上做的区别works.sequence
在于,您失去了效果由不同部分组成的事实。如果您部分运行流,这将浮出水面,例如通过执行以下操作:
stream.take(3).compile.drain
如果您不排序,它只会运行works
. 如果你这样做,它将运行所有这些。
从 Luis Miguel 提出的其他选项中,只有unfoldEval
一个保留了分离,但这可能是一种矫枉过正。