scala - 使用 ZIO 提前中止

标签 scala functional-programming fold zio

我想为 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/

相关文章:

javascript - 用函数式编程风格计算数字?

powershell - PowerShell中的特定bash命令(折叠-w1)?

haskell - 为什么非多态类型不能在 Haskell 中实现可折叠?

scala - Spark 列因式分解

functional-programming - 有人可以解释一下方案中的这种延续吗?

scala - 您可以为 None 指定类型参数或告诉编译器它是一个 Option[String] 吗?

java - 需要在 FileNameFilter 接口(interface)的 lambda 表达式内构造文件实例

recursion - 使用fold_left/right反转OCaml中的列表

scala - 更改 Spark 的 Hadoop 版本

scala - 为什么 map.size 在 map 不为空时返回 0