2016-06-12 3 views
8

мне нужно придавить последовательность cats.data.ValidatedNel[E, T] значений одного ValidatedNel значения:Как придавить последовательность ValidatedNel кошек значения

val results: Seq[cats.data.ValidatedNel[E, T]] = ??? 

val flattenedResult: cats.data.ValidatedNel[E, T] 

я могу сделать это так:

import cats.std.list._, cats.syntax.cartesian._ 

results.reduce(_ |@| _ map { case _ => validatedValue }) 

но если существуют предопределенные методы библиотеки.

ответ

10

Это зависит от того, как вы хотите, чтобы объединить их

import cats.data.{Validated, ValidatedNel} 
import cats.implicits._ 

val validations1 = List(1.validNel[String], 2.valid, 3.valid) 
val validations2 = List(1.validNel[String], "kaboom".invalidNel, "boom".invalidNel) 

Если вы хотите совместить T с, вы можете использовать Foldable.combineAll который использует Monoid[T] (что validatedValue в вашем вопросе?):

val valSum1 = validations1.combineAll 
// Valid(6) 
val valSum2 = validations2.combineAll 
// Invalid(OneAnd(kaboom,List(boom))) 

Если вы хотите, чтобы получить ValidationNel[String, List[T]], вы можете использовать Traverse.sequenceU:

val valList1: ValidatedNel[String, List[Int]] = validations1.sequenceU 
// Valid(List(1, 2, 3)) 
val valList2: ValidatedNel[String, List[Int]] = validations2.sequenceU 
// Invalid(OneAnd(kaboom,List(boom))) 

Если вас не волнует результат, который, кажется, имеет место, вы можете использовать Foldable.sequenceU_.

val result1: ValidatedNel[String, Unit] = validations1.sequenceU_ 
// Valid(()) 
val result2: ValidatedNel[String, Unit] = validations2.sequenceU_ 
// Invalid(OneAnd(kaboom,List(boom))) 

validations1.sequenceU_.as(validatedValue) // as(x) is equal to map(_ => x) 
+0

Извините, '' 'в исходном вопросе (теперь' validatedValue') является значением, которое проверяется, то есть 'T'. – Tvaroh

+0

Похоже, 'combAll' - это то, что мне нужно. Мне нужно было добавить вызов '.toList' на мой' Seq', btw. – Tvaroh

+0

@Tvaroh Да, у кошек нет экземпляров класса типа для 'Seq', поэтому вам нужно перейти в' List' или 'Vector'. –