1

我有一个List[IO[Unit]]IO. 我想把它转换成Stream[IO,Unit]

目前,我所做的是这个

val works: List[IO[Unit]]
works.map(work => Stream.eval(work)).reduceLeft((left, right) => left ++ right)

有没有更好的办法?

4

2 回答 2

3

我可以想到这三个替代方案:(
注意,我只是检查了它们的类型检查,但我没有运行它们)

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 =>

于 2020-04-10T00:46:08.153 回答
2

我建议做其中之一:

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一个保留了分离,但这可能是一种矫枉过正。

于 2020-04-10T10:01:17.433 回答