【问题标题】:How to chain Future[\/[A,B]] in scala?如何在 Scala 中链接 Future[\/[A,B]]?
【发布时间】:2014-02-24 16:02:30
【问题描述】:

我如何对Future[\/[String,Int]] 类型的数据进行for 理解

这里是一个起点,不能编译。

import scala.concurrent.{ExecutionContext,future,Future}
import scalaz._
import Scalaz._
import ExecutionContext.Implicits.global

def calculateStuff(i:Int):Future[\/[String,Int]] = future{\/-(i)}

for {
   v1Either <- calculateStuff(1)
   v1Int <- v1Either
   v2Either < calculateStuff(v1Int)
   v2Int <- v2Either
   v3Either <- calculateStuff(v2Int)
   v3Int <- v3Either
} yield {
   v1Int + v2Int + v3Int
}

注意:calculateStuff 只是一个例子,实际上会有不同的功能,每个取决于前面的结果。

【问题讨论】:

    标签: scala scalaz monad-transformers


    【解决方案1】:

    首先我应该注意,我假设您有充分的理由实现自己的错误处理(通过 \/),而不是使用内置于 Future 中的功能

    如果是这种情况,那么正如您的标签所暗示的那样,这种问题正是 monad 转换器的用途——只需将您的计算包装在 EitherT 中:

    import scalaz._, Scalaz._, contrib.std._
    import scala.concurrent.{ ExecutionContext, future, Future }
    import ExecutionContext.Implicits.global
    
    def calculateStuff(i: Int): EitherT[Future, String, Int] =
      EitherT(future(\/-(i)))
    
    val computation = for {
       v1Int <- calculateStuff(1)
       v2Int <- calculateStuff(v1Int + 1)
       v3Int <- calculateStuff(v2Int + 2)
    } yield v1Int + v2Int + v3Int
    

    请注意,我正在使用来自Typelevelscalaz-contrib 库的FutureMonad 实例。

    现在computation.run 会给你一个Future[String \/ Int]

    如果你需要在计算中注入一个纯值,你可以使用point 和一个 lambda 类型:

    v4Int <- 1.point[({ type L[x] = EitherT[Future, String, x] })#L]
    

    您还可以定义自己的类型别名以使其看起来更漂亮。

    如果您想在for-comprehension 中使用\/ 值,您可以将其指向Future 并将整个内容包装在EitherT 中:

    v5Int <- EitherT(1.right[String].point[Future])
    

    也可以将一个普通的旧 Future 提升到转换后的 monad 中,使用 liftM(有点令人困惑的名称):

    v6Int <- future(1).liftM[({ type T[m[+_], a] = EitherT[m, String, a] })#T]
    

    在这种情况下,您几乎肯定需要一个类型别名——该行主要是噪音。

    【讨论】:

    • 哇,这就是我一直在寻找的东西,但无法让它工作。你的假设是正确的,我确实有一个理由,至少现在是这样。感谢这个震撼的答案!
    • 我怎样才能混入一个结果很简单的函数\/?
    • 谢谢!我担心我需要添加大量管道工或重构代码库才能开始使用您的解决方案。在您的最后一个示例中,它甚至只能在我正在处理的函数的上下文中使用。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 2020-10-17
    相关资源
    最近更新 更多