如何将 Future 的 disjunction 转化为 disjunction 的 Future
How to transform disjunction of Future to Future of disjunction
我有一个方法的结果:
val res: Future[Int] Xor Future[String] = getResult(x)
并想对其进行转换并将其用作 Future[Int Xor String]
我无法从 herding cats blog 推断出我的用例,我不确定 monad 转换器是否是这里的正确工具,也许是某种形式的 traverse
?
来自 cats 的 Xor
代表任何分离。 Scalaz \/
或 stdlib Either
也可以(尽管我更喜欢有偏见的析取)。
谢谢
Scalaz 有 Functor.counzip
,但 scalaz.syntax.functor
中没有 counzip
,所以我们需要直接在 Functor[Future]
上调用它:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz.std.scalaFuture._
import scalaz.{\/, Functor}
val disj: Future[Int] \/ Future[String] = \/.right(Future.successful("foo"))
Functor[Future].counzip(disj)
// Future[Int \/ String] : Success(\/-(foo))
Scalaz 也有一个 Cozip
类型 class,它给你相反的结果:F[A \/ B] => F[A] \/ F[B]
.
正如 sequence
允许您将 F[G[A]]
变成 G[F[A]]
当 F
有一个 Traverse
实例并且 G
是applicative,如果 F
有一个 Bitraverse
实例(并且 G
是适用的),bisequence
可以让你把 F[G[A], G[B]]
变成 G[F[A, B]]
。
Cats 已经为 at least a couple of versions 提供了 Bitraverse
实现(我这里使用的是 0.6.0-M2),所以你可以这样写:
import cats.data.Xor, cats.std.future._, cats.syntax.bitraverse._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def flip[A, B](x: Xor[Future[A], Future[B]]): Future[Xor[A, B]] = x.bisequence
Bitraverse
有点像 Scalaz 的 Zip
或 Cozip
(在另一个答案中提到),但它更通用,因为可以为具有两个的任何类型构造函数定义实例类型参数(假设它具有适当的语义),而不仅仅是元组或析取。
我有一个方法的结果:
val res: Future[Int] Xor Future[String] = getResult(x)
并想对其进行转换并将其用作 Future[Int Xor String]
我无法从 herding cats blog 推断出我的用例,我不确定 monad 转换器是否是这里的正确工具,也许是某种形式的 traverse
?
Xor
代表任何分离。 Scalaz \/
或 stdlib Either
也可以(尽管我更喜欢有偏见的析取)。
谢谢
Scalaz 有 Functor.counzip
,但 scalaz.syntax.functor
中没有 counzip
,所以我们需要直接在 Functor[Future]
上调用它:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz.std.scalaFuture._
import scalaz.{\/, Functor}
val disj: Future[Int] \/ Future[String] = \/.right(Future.successful("foo"))
Functor[Future].counzip(disj)
// Future[Int \/ String] : Success(\/-(foo))
Scalaz 也有一个 Cozip
类型 class,它给你相反的结果:F[A \/ B] => F[A] \/ F[B]
.
正如 sequence
允许您将 F[G[A]]
变成 G[F[A]]
当 F
有一个 Traverse
实例并且 G
是applicative,如果 F
有一个 Bitraverse
实例(并且 G
是适用的),bisequence
可以让你把 F[G[A], G[B]]
变成 G[F[A, B]]
。
Cats 已经为 at least a couple of versions 提供了 Bitraverse
实现(我这里使用的是 0.6.0-M2),所以你可以这样写:
import cats.data.Xor, cats.std.future._, cats.syntax.bitraverse._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def flip[A, B](x: Xor[Future[A], Future[B]]): Future[Xor[A, B]] = x.bisequence
Bitraverse
有点像 Scalaz 的 Zip
或 Cozip
(在另一个答案中提到),但它更通用,因为可以为具有两个的任何类型构造函数定义实例类型参数(假设它具有适当的语义),而不仅仅是元组或析取。