[英]How to get Future[\/[Throwable, T]] from several Future[\/[Throwable, T]]
Assuming I have several methods to return \\/[Throwable, String]
. 假设我有几种方法可以返回\\/[Throwable, String]
。 The right value Int
is what I want and the left value accumulates errors. 正确的值Int
是我想要的,左值累积错误。
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
It looks good, because scalaz either's flatmap is right biased, so it will operate based on the right value. 它看起来不错,因为scalaz要么平面图是正确的偏差,所以它将基于正确的值运行。
However, if method is going to change for the API call, so the return type would be Future[ErrorOr[T]]
. 但是,如果要为API调用更改方法,则返回类型将为Future[ErrorOr[T]]
。 Is there any way I can use to return Future[ErrorOr[T]]
? 有什么方法可以用来返回Future[ErrorOr[T]]
吗? Also, I probably want to use future.flatMap
as a callback instead of using await
here to block 另外,我可能想使用future.flatMap
作为回调,而不是使用await
来阻止
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)
您可以将init
的结果包装在EitherT
monad转换器中,使用flatMapF
而不是flatMap
来直接使用add
和multiply
,就像现在一样,然后调用run
来获取Future[ErrorOr[Int]]
:
EitherT(init(3)).flatMapF(add(_, 4)).flatMapF(multiply(_, 3)).run
You might consider using scalaz.concurrent.Task
: 您可以考虑使用scalaz.concurrent.Task
:
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)
So: 所以:
scala> val res = init(3).flatMap(add(_, 4)).flatMap(multiply(_, 3))
res: scalaz.concurrent.Task[Int] = scalaz.concurrent.Task@3fdb3076
Can be easily converted to: 可以很容易地转换为:
scala> res.get
res1: scalaz.concurrent.Future[scalaz.\/[Throwable,Int]] = ...
scala> res.get.run
res5: scalaz.\/[Throwable,Int] = \/-(21)
If you need to fail: 如果您需要失败:
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)
Please note, that the Future
here is scalaz.concurrent.Future
请注意,这里的Future
是scalaz.concurrent.Future
Update 更新
If you need to pass Either
to the Task - you can use this: 如果您需要将Either
传递给任务 - 您可以使用:
import Task._
implicit class FutureToTask[T](f: Future[\/[Throwable, T]]){
def task = async(f.runAsync)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.