2016-11-01 5 views
3

У меня есть последовательность ошибок или представлений (Seq[Xor[Error,View]])Кошки Seq [Xor [A, B]] => Xor [А, Seq [B]]

Хочу карту это к Xor первого ошибка (если таковая имеется) или Последовательность просмотров (или, возможно, просто (Xor[Seq[Error],Seq[View])

Как это сделать?

+0

Имя функции для этого типа метода - это «последовательность», которая является частным случаем «обхода». Вы что-то, что обеспечит явное превращение Xor в Traverse, я верю. https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/Traverse.scala –

ответ

5

Вы можете использовать sequenceU, предоставляемый синтаксисом bitraverse, похожий на то, что вы бы сделали со сказазом. Похоже, что для классов 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

В самой последней версии Кошки Xor удаляется, и теперь используется стандартный Scala Either тип данных.

Майкл Zajac правильно показал, что вы можете использовать sequence или sequenceU (который на самом деле определяется на Traverse не Bitraverse), чтобы получить Either[Error, List[View]].

import cats.implicits._ 

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

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

Вы можете посмотреть на traverse (который, как map и sequence), который вы можете использовать большую часть времени вместо 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 и Validated на сайте кошек.

Смежные вопросы