【问题标题】:Error handling with Either in Scala在 Scala 中使用 Either 处理错误
【发布时间】:2014-11-01 05:53:29
【问题描述】:

这是我之前的question 的后续。假设我有以下功能:

type Result[A] = Either[String, A] // left is an error message

def f1(a: A): Result[B] = ...
def f2(b: B): Result[C] = ...
def f3(c: C): Result[D] = ...

def f(a: A): Result[D] = for {
  b <- f1(a).right
  c <- f2(b).right
  d <- f3(c).right
} yield d; 

假设我还想在错误消息中添加更多信息。

 def f(a: A): Result[D] = for {
  b <- { val r = f1(a); r.left.map(_ + s"failed with $a"); r.right }
  c <- { val r = f2(b); r.left.map(_ + s"failed with $a and $b"); r.right }
  d <- { val r = f3(c); r.left.map(_ + s"failed with $a, $b, and $c"); r.right } 
} yield d; 

代码看起来很难看。你会如何建议改进代码?

【问题讨论】:

  • 为什么不只是f1(a).left.map(_ + s"failed with $a").right
  • 谢谢。你是对的。
  • 是否有任何理由不将参数附加到函数 f1、f2、f3 中的错误消息中?
  • 最好使用Scalaz'\/,它有右偏。 Scala 的 Either 不适合这个。

标签: scala error-handling either


【解决方案1】:

代码看起来很丑,因为你在重复自己。

改为写一个方法!或者扩展方法。其中之一,也许是:

implicit class StringEitherCanAdd[A](private val e: Either[String, A]) extends AnyVal {
  def info(s: String): Either[String, A] = e.left.map(_ + s)
  def failed(a: Any*): Either[String, A] =
    if (a.length == 0) e
    else if (a.length == 1) e.left.map(_ + s"failed with ${a(0)}")
    else if (a.length == 2) e.left.map(_ + s"failed with ${a(0)} and ${a(1)}")
    else e.left.map(_ + s"failed with ${a.init.mkString(", ")}, and ${a.last}")
}

现在你只是

f1(a).info(s"failed with $a").right
f2(b).failed(a,b).right

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2015-01-26
    • 1970-01-01
    • 2010-11-14
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多