嵌套对期货的理解

时间:2015-07-09 19:51:18

标签: scala

假设:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

def f: Future[Either[String, Int]] = Future { Right(100)}

def plus10(x: Int): Future[Either[String, Int]] = 
    Future { Right(x + 10) }

我正试图将Future[...]链接起来:

scala> for { 
     |  x <- f
     |  y <- for { a <- x.right } yield plus10(a)
     | } yield y
<console>:17: error: value map is not a member of Product with 
    Serializable with 
   scala.util.Either[String,scala.concurrent.Future[Either[String,Int]]]
        y <- for { a <- x.right } yield plus10(a)
                     ^

我希望得到:Future{Right(100)},但是我得到了上面的编译时错误。

Travis Brown就如何使用Monad Transformers来修复我的代码here给出了一个很好的答案。但是,如何修复我的代码没有 Monad Transformers?

2 个答案:

答案 0 :(得分:1)

原来我可以使用Either#fold

 scala> for { 
     |  a <- f
     |  b <- a.fold(_ => Future { Left("bad") }, xx => plus10(xx) )
     | } yield b
res16: scala.concurrent.Future[Either[String,Int]] = 
     scala.concurrent.impl.Promise$DefaultPromise@67fc2aad

scala> res16.value
res17: Option[scala.util.Try[Either[String,Int]]] = 
          Some(Success(Right(110)))

答案 1 :(得分:1)

当你出现时,我正准备回答,但你仍然可以看看这个:

val res = for {
  x <- f
  y <- x.fold(x => Future{Left(x)}, plus10)
} yield y

右侧更简洁,保持左侧。