我想为 abort-early-in-a-fold 添加一个答案对于ZIO。
所以我采用了猫的解决方案:cats solution
def sumEvenNumbers(nums: Stream[Int]): Option[Long] = {
import cats.implicits._
nums.foldM(0L) {
case (acc, c) if c % 2 == 0 => Some(acc + c)
case _ => None
}
}
ZIO 如何实现这一目标?
我得到的最接近的:
new DefaultRuntime {}
.unsafeRun(sumEvenNumbers(List(2,4,6,3,5,6)))
def sumEvenNumbers(nums: Iterable[Int]): ZIO[Any, Nothing, Int] = {
stream.Stream.fromIterable(nums)
.run(Sink.fold(0)(s => s % 2 == 0) { (a: Int, b: Int) => (a + b, Chunk.empty)
})
}
但这给了我:15
而不是 12
。所以它看起来短路但是它需要的数量太多了。它是 Int
而不是 Option[Int]
。
最佳答案
没有zio.stream.Stream
的解决方案:
def sumEvenNumbers(as: Iterable[Int]): UIO[Option[Int]] =
ZIO
.foldLeft(as)(0)((s, a) => if (a % 2 == 0) ZIO.succeed(s + a) else ZIO.fail(s))
.option
- 使用
.foldLeft
- 一旦数字不是偶数 - 折叠失败。 - 使用
.option
将错误 channel 合并到成功 channel 到选项
。
关于scala - 使用 ZIO 提前中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59735240/