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

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

我有一系列错误或视图 (Seq[Xor[Error,View]])

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

我该怎么做?

您可以使用 bitraverse 语法提供的 sequenceU,类似于您对 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)))

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

Michael Zajac 正确显示您可以使用 sequencesequenceU(实际上是在 Traverse 而不是 Bitraverse 上定义的)来获得 Either[Error, List[View]] .

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]的类型别名.

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

您可以在猫网站 Either and Validated 上找到更多示例和信息。