3

我有一个方法的结果: val res: Future[Int] Xor Future[String] = getResult(x)

并想对其进行改造并将其用作Future[Int Xor String]

我无法从牧猫博客中推断出我的用例,并且不确定 monad 转换器是否是正确的工具,也许是某种形式的traverse?

Xorfrom cat 代表任何分离。Scalaz\/或 stdlibEither也可以(尽管我更喜欢有偏见的析取)。

谢谢

4

2 回答 2

10

就像sequence允许你将 aF[G[A]]变成一个G[F[A]]whenF有一个Traverse实例并且G是可应用的一样,bisequence让你将 aF[G[A], G[B]]变成 a G[F[A, B]]ifF有一个Bitraverse实例(并且G是可应用的)。

Cats 提供了至少几个版本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 的Zipor Cozip(在另一个答案中提到),但它更通用,因为可以为具有两个类型参数的任何类型构造函数定义实例(假设它具有适当的语义),而不仅仅是元组或析取。

于 2016-05-19T16:06:40.710 回答
3

Scalaz 有Functor.counzip,但没有counzipinscalaz.syntax.functor所以我们需要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类型类,它为您提供逆:F[A \/ B] => F[A] \/ F[B]

于 2016-05-19T15:36:26.593 回答