我有一个方法的结果:
val res: Future[Int] Xor Future[String] = getResult(x)
并希望对其进行转换并将其用作Future[Int Xor String]
我无法从herding cats blog推断出我的用例,我不确定monad变换器是否是正确的工具,也许是某种形式的traverse
?
Xor
代表任何分离。 Scalaz \/
或stdlib Either
也可以(虽然我更喜欢有偏见的分离)。
谢谢
答案 0 :(得分:9)
正如sequence
允许您在F[G[A]]
有G[F[A]]
个实例且F
适用时Traverse
允许您将G
变为bisequence
, F[G[A], G[B]]
允许您将G[F[A, B]]
变为F
,如果Bitraverse
有G
个实例(并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]
。