3

我试图找到最方便的方法来规范化一个“上”层中的 scalaz.Validations 中的错误类型,该层调用返回“下”层上具有不同错误类型的验证的方法。自然地,需要为每个较低级别的错误类型定义一个到上层错误类型的映射,但我似乎无法绕过在 for 理解中提供显式类型提示,以便获取我的隐式。我想将错误类型的显式转换(例如通过 .fail.map(...).validation如下:

package errorhandling

import scalaz._
import Scalaz._

class LowerServiceA {
  def doStuff(): Validation[LowerServiceAError, Int] = Success(1)
}
sealed trait LowerServiceAError
// ... more specific error types

class LowerServiceB {
  def doStuff(): Validation[LowerServiceBError, Int] = Success(1)
}
sealed trait LowerServiceBError
// ... more specific error types

class LowerServiceC {
  def doStuff(): Validation[LowerServiceCError, Int] = Success(1)
}
sealed trait LowerServiceCError
// ... more specific error types

sealed trait UpperError {}
// ... more specific error types
trait IsUpperError[E] {
  def apply(e: E): UpperError
}
object IsUpperError {
  implicit val lowerServiceAErrorIsUpperError: IsUpperError[LowerServiceAError] = new IsUpperError[LowerServiceAError] {
    def apply(err: LowerServiceAError) = new UpperError {}
  }

  implicit val lowerServiceBErrorIsUpperError: IsUpperError[LowerServiceBError] = new IsUpperError[LowerServiceBError] {
    def apply(err: LowerServiceBError) = new UpperError {}
  }

  implicit val lowerServiceCErrorIsUpperError: IsUpperError[LowerServiceCError] = new IsUpperError[LowerServiceCError] {
    def apply(err: LowerServiceCError) = new UpperError {}
  }
}

object UpperError {
  implicit def upperError[E: IsUpperError, A](v: Validation[E, A]): Validation[UpperError, A] =
    v.fail.map(e => implicitly[IsUpperError[E]].apply(e)).validation
}

class UpperService(serviceA: LowerServiceA, serviceB: LowerServiceB, serviceC: LowerServiceC) {
  def doStuff(): Validation[UpperError, Int] = {
    for {
      // I'd like to avoid the repeated type-hints or .fail.map(...).validation here
      a <- serviceA.doStuff() // : Validation[UpperError, Int]
      b <- serviceB.doStuff() // : Validation[UpperError, Int]
      c <- serviceC.doStuff()
    } yield a + b + c
  }
}

没有类型提示的编译器错误(2.9.2):

ErrorHandling.scala:56: error: could not find implicit value for evidence parameter of type errorhandling.IsUpperError[java.lang.Object]
  b <- serviceB.doStuff() //: Validation[UpperError, Int]
    ^

发现一个错误

如果做这种事情的愿望暗示了我如何处理这种错误处理的问题,我也很感激指导。

4

0 回答 0