如何将未来的分离转化为分离的未来

时间:2016-05-19 15:06:52

标签: scala scalaz monad-transformers scala-cats

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

并希望对其进行转换并将其用作Future[Int Xor String]

我无法从herding cats blog推断出我的用例,我不确定monad变换器是否是正确的工具,也许是某种形式的traverse

来自猫的

Xor代表任何分离。 Scalaz \/或stdlib Either也可以(虽然我更喜欢有偏见的分离)。

谢谢

2 个答案:

答案 0 :(得分:9)

正如sequence允许您在F[G[A]]G[F[A]]个实例且F适用时Traverse允许您将G变为bisequenceF[G[A], G[B]]允许您将G[F[A, B]]变为F,如果BitraverseG个实例(并Bitraverse适用)。

Cats为at least a couple of versions提供了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 实现(我这里使用的是0.6.0-M2),所以你可以这样写:

Bitraverse

Zip有点像Scalaz的Cozip getHeroes (): Observable<Hero[]> { return this.http.get(this.heroesUrl) .map(this.extractData) .catch(this.handleError); } addHero (name: string): Observable<Hero> { let body = JSON.stringify({ name }); let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); return this.http.post(this.heroesUrl, body, options) .map(this.extractData) .catch(this.handleError); } private extractData(res: Response) { let body = res.json(); return body.data || { }; } private handleError (error: any) { // In a real world app, we might use a remote logging infrastructure // We'd also dig deeper into the error to get a better message let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error'; console.error(errMsg); // log to console instead return Observable.throw(errMsg); } (在另一个答案中提到),但它更通用,因为可以为任何具有两个类型参数的类型构造函数定义实例(假设它具有适当的语义),而不仅仅是元组或析取。

答案 1 :(得分:3)

Scalaz有Functor.counzip,但counzip中没有scalaz.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]

相关问题