如何从返回Future的方法中获得Left?

时间:2018-12-16 13:42:37

标签: scala

def myMethod(myType: String) :Future[Future[Either[List[MyError], MyClass]]] {
   for {
     first <- runWithSeq(firstSource)
   }
   yield {
     runWithSeq(secondSource) 
     .map {s -> 
        val mine = MyClass(s.head, lars)
        val errors = myType match {
          case "all" => Something.someMethod(mine)
        }
        (s, errors)
     } 
     .map { x => 
        x._2.leftMap(xs => { 
          addInfo(x._1.head, xs.toList)
        }).toEither
     }
   }
}

for {
  myStuff <- myMethod("something")
} yield {
  myStuff.collect {
   case(Left(errors), rowNumber) => 
    MyCaseClass(errors, None) //compilation error here
  }
}

我在MyCaseClass上遇到expected: List[MyError], found: Any

的编译错误

MyCaseClass的签名是:

case class MyCaseClass(myErrors: List[ValidationError])

如何解决此问题,以便可以在MyCaseClass内正确调用yield

2 个答案:

答案 0 :(得分:1)

您的示例很难粘贴和修复​​

此内容的摘要示例 C类可能是您想要的

def test(testval: Int)(implicit ec: ExecutionContext): Future[Future[Either[String, Int]]] = {
  Future(Future{
    if (testval % 2 == 0) Right(testval) else Left("Smth wrong")
  })
}

implicit class FutureEitherExt[A, B](ft: Future[Either[A, B]]) {
  def EitherMatch[C](f1: A => C, f2: B => C)(implicit ec: ExecutionContext): Future[C] = {
    ft.map {
      case Left(value) => f1(value)
      case Right(value) => f2(value)
    }
  }
}

val fl: Future[Either[String, Int]] = test(5).flatten

val result: Future[String] = fl.EitherMatch(identity, _.toString)

答案 1 :(得分:1)

您的代码示例没有多大意义,也无法编译,但是如果runWithSeq()返回一个Future,那么您应该可以消除双精度Future这样的返回类型这样。

for {
  _    <- runWithSeq(firstSource)
  scnd <- runWithSeq(secondSource)
} yield { ...