猫Seq [Xor [A,B]] => Xor [A,Seq [B]]

时间:2016-11-01 23:45:44

标签: scala scala-cats

我有一系列错误或观点(Seq[Xor[Error,View]]

我想将其映射到第一个错误(如果有)或视图序列的Xor (Xor[Error, Seq[View]])或可能只是(Xor[Seq[Error],Seq[View]

我该怎么做?

2 个答案:

答案 0 :(得分:6)

您可以使用sequenceU语法提供的bitraverse,与您对scalaz的处理方式类似。虽然Seq似乎不存在正确的类型类,但您可以使用List

import cats._, data._, implicits._, syntax.bitraverse._

case class Error(msg: String)

case class View(content: String)

val errors: List[Xor[Error, View]] = List(
  Xor.Right(View("abc")), Xor.Left(Error("error!")), 
  Xor.Right(View("xyz"))
)

val successes: List[Xor[Error, View]] = List(
  Xor.Right(View("abc")),
  Xor.Right(View("xyz"))
)

scala> errors.sequenceU
res1: cats.data.Xor[Error,List[View]] = Left(Error(error!))

scala> successes.sequenceU
res2: cats.data.Xor[Error,List[View]] = Right(List(View(abc), View(xyz)))

答案 1 :(得分:2)

在最新版本的Cats Xor已删除,现在使用标准的Scala Either数据类型。

Michael Zajac正确地表明您可以使用sequencesequenceU(实际上Traverse而不是Bitraverse定义)来获得Either[Error, List[View]]。< / p>

import cats.implicits._

val xs: List[Either[Error, View]] = ???

val errorOrViews: Either[Error, List[View]] = xs.sequenceU

您可能希望查看traverse(类似于mapsequence),您可以使用大部分时间而不是sequence }。

如果您希望所有失败的错误,则无法使用Either,但您可以使用Validated(或ValidatedNel,这只是Validated[NonEmptyList[A], B]的类型别名。< / p>

import cats.data.{NonEmptyList, ValidatedNel}

val errorsOrViews: ValidatedNel[Error, List[View]] = xs.traverseU(_.toValidatedNel)

val errorsOrViews2: Either[NonEmptyList[Error], List[View]] = errorsOrViews.toEither

您还可以使用MonadCombine.separate获取错误:

val errorsAndViews: (List[Error], List[View]) = xs.separate

您可以在Cats网站上找到有关EitherValidated的更多示例和信息。