如何在 Scala 中重构嵌套的 Option.folds?

How to refactor nested Option.folds in Scala?

假设我用给定的 f1: Int => Option[Int]f2: Int => Option[Int] 编写 foo:Int => Status 如下:

def f1(x: Int): Option[Int] = ???
def f2(y: Int): Option[Int] = ???

sealed trait Status
object Error1 extends Status
object Error2 extends Status
case class Ok(x:Int) extends Status

// probably not necessary
def error1: Status = Error1
def error2: Status = Error2
def ok(z: Int): Status = Ok(z)

def foo(x: Int): Status = f1(x).fold(error1){y => f2(y).fold(error2){z => ok(z)}}

IMO 嵌套 folds 看起来很笨拙。你会如何重构它?

如果您喜欢使用 Either,您可以执行以下操作。比较好看,能不能看得懂就看你对哪一个都放心了。

val either = for {
  y <- f1(x).toRight(error1).right
  z <- f2(y).toRight(error2).right
} yield ok(z)

either.merge

一些背景:

如果定义了选项,

Option.toRight 转换为 Right(成功案例),否则 returns 参数的 Left(错误案例)。

Either.rightEither 投射到右边,即单子操作使得 RightSomeLeftNone , 但如果我们在左边的情况下,它会保留 Left 值。

Either.merge 仅适用于 Either[A, A] 和 returns LeftRight.

中的任何值