Scala 2.12组合了Future和Either(有偏见的版本)

时间:2017-07-27 07:49:57

标签: scala

我有两个方法,两个都返回Future [Either [String,T]],并希望将它们链接在一起以完成工作。我正在使用Scala 2.12现在两者都是正确的偏见。

例如,

如果函数没有返回Future和Either组合,我可以简单地执行以下操作以获得理解。

def convert(a, b) = ???
def callA(): Future[A] = ???
def callB(a: A): Future[B] = ???

def chain: Future[C] = for {
  a <- callA
  b <- callB(a)
} yield convert(a, b)

但现在我想使用以下语法使用Either捕获错误,并传播到最终结果。实现这一目标的最佳方法是什么?还应该使用callB还是callB1?

def convert(a, b): Future[Either[String, C]] = ???
def callA(): Future[Either[String, A]] = ???
def callB(a: A): Future[Either[String, B]] = ??? or 
def callB1(eithera: Either[String, A]): Future[Either[String, B]] = ???

我知道使用cat变换monad可以简化这一点。欢迎给我使用标准库和猫的解决方案。

1 个答案:

答案 0 :(得分:6)

正如评论所提到的,这是猫和scalaz可以处理的事情。但我也能理解不要为一小段逻辑引入另一个依赖或复杂的愿望。如果你想自己实现它,你可以做什么:

implicit class FutureEither[A](val wrapped: Future[Either[String, A]])(implicit ec: ExecutionContext) {
  def map[B](f: A => B): FutureEither[B] = wrapped.map(_.map(f))

  def flatMap[B](f: A => FutureEither[B]): FutureEither[B] = wrapped.flatMap {
    case Left(s) => Future(Left(s))
    case Right(a) => f(a).wrapped
  }
}

使用适当的类型实现mapflatMap可以实现完全相同的理解:

def convert(a: A, b: B): C = ???
def callA(): FutureEither[A] = ???
def callB(a: A): FutureEither[B] = ???

def chain: FutureEither[C] = for {
  a <- callA()
  b <- callB(a)
} yield convert(a, b)