首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从几个未来获得未来[\/[Throwable,T]] [\/[Throwable,T]]

如何从几个未来获得未来[\/[Throwable,T]] [\/[Throwable,T]]
EN

Stack Overflow用户
提问于 2016-02-23 19:24:18
回答 2查看 134关注 0票数 3

假设我有几个返回\/[Throwable, String]的方法。右边的值Int是我想要的,左边的值累积错误。

代码语言:javascript
复制
import scalaz._
import Scalaz._
type ErrorOr[T] = \/[Throwable, T]

def init(a: Int): ErrorOr[Int] = a.right
def add(a: Int, b: Int): ErrorOr[Int] = (a + b).right
def multiply(a: Int, b: Int): ErrorOr[Int] = (a * b).right

init(3).flatMap(add(_, 4)).flatMap(multiply(_, 3)) // 21

它看起来很好,因为scalaz的平面映射是有偏向的,所以它将基于正确的值进行操作。

但是,如果要为API调用更改方法,则返回类型将为Future[ErrorOr[T]]。有什么方法可以用来返回Future[ErrorOr[T]]吗?此外,我可能希望使用future.flatMap作为回调,而不是在这里使用await来阻止

代码语言:javascript
复制
def init(a: Int): Future[ErrorOr[Int]] = Future(a.right)
def add(a: Int, b: Int): Future[ErrorOr[Int]] = Future((a + b).right)
def multiply(a: Int, b: Int): Future[ErrorOr[Int]] = Future((a * b).right)
EN

回答 2

Stack Overflow用户

发布于 2016-02-23 19:45:11

您可以将init的结果包装在EitherT monad转换器中,使用flatMapF而不是flatMap直接使用addmultiply,然后调用run以获取Future[ErrorOr[Int]]

代码语言:javascript
复制
EitherT(init(3)).flatMapF(add(_, 4)).flatMapF(multiply(_, 3)).run
票数 3
EN

Stack Overflow用户

发布于 2016-02-23 20:22:38

您可以考虑使用scalaz.concurrent.Task

代码语言:javascript
复制
def init(a: Int): Task[Int] = Task.now(a)
def add(a: Int, b: Int): Task[Int] = Task.now(a + b)
def multiply(a: Int, b: Int): Task[Int] = Task.now(a * b)

所以:

代码语言:javascript
复制
scala> val res = init(3).flatMap(add(_, 4)).flatMap(multiply(_, 3))
res: scalaz.concurrent.Task[Int] = scalaz.concurrent.Task@3fdb3076

可以很容易地转换为:

代码语言:javascript
复制
scala> res.get
res1: scalaz.concurrent.Future[scalaz.\/[Throwable,Int]] = ...

scala> res.get.run
res5: scalaz.\/[Throwable,Int] = \/-(21)

如果您需要失败:

代码语言:javascript
复制
scala> def add(a: Int, b: Int): Task[Int] = Task.fail(new RuntimeException("fail"))
add: (a: Int, b: Int)scalaz.concurrent.Task[Int]

scala> init(3).flatMap(add(_, 4)).flatMap(multiply(_, 3)).get.run
res4: scalaz.\/[Throwable,Int] = -\/(java.lang.RuntimeException: fail)

请注意,这里的Futurescalaz.concurrent.Future

更新

如果您需要将Either传递给任务-您可以使用以下命令:

代码语言:javascript
复制
import Task._

implicit class FutureToTask[T](f: Future[\/[Throwable, T]]){
   def task = async(f.runAsync)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35576257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档