如何优雅地结合两个 Either 的结果

How to graciously combine results from two Either's

我有一个函数需要合并两个 Either 对象的结果。

如果 "handlingResult" 是右,我需要 "request" 的右侧,并且如果 "handlingResult" 是右,那么 "request" 也是给定的事实一个权利。

如果 "handlingResult" 是 Left,我需要它的值来构建响应。

现在这是实现(FailingResponse 和 SuccessfulResponse 都扩展了 ValuationResponse):

def getResponse(handlingResult : Either[FailureReason, List[StockValuation]]
               ,request        : Either[Error, ValuationRequest]
               ): ValuationResponse = {

  handlingResult.fold(
      failureReason =>
          FailingResponse(failureReason.message
                         ,failureReason.statusCode),
      listOfValuations =>
          SuccessfulResponse(listOfValuations
                            ,request.right.get.symbol
                            ,request.right.get.function
                            ,StatusCodes.SUCCESS))
}

但我怀疑直接访问 either 不是一个好的做法,例如

request.right.get.symbol

实现相同行为但以值得推荐的方式进行的好方法是什么?

两者在 Scala 2.12 及更高版本中都是右偏的,因此您可以使用 for-comprehension

  def getResponse(handlingResult : Either[FailureReason, List[StockValuation]]
                  ,request        : Either[Error, ValuationRequest]
                 ): ValuationResponse = {
    val result = for {
      result <- handlingResult
      req <- request
    } yield {
      SuccessfulResponse(result, req.symbol, req.function, SUCCESS)
    }
    result match {
      case Right(resp) => resp
      case Left(FailureReason(msg, code)) => FailingResponse(msg, code)
      case Left(Error) => FailingResponse("failed for unknown reasons", SOME_NEW_CODE)
    }
  }

请注意,虽然您不希望最后一个 case 语句匹配,但为了完整性,它应该存在,并且可以创建一个新代码 SOME_NEW_CODE 来指示意外情况发生了。