2016-06-12 26 views
8

ho bisogno di appiattire una sequenza di cats.data.ValidatedNel[E, T] valori per un singolo ValidatedNel valore:Come appiattire una sequenza di ValidatedNel gatti valori

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

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

posso farlo in questo modo:

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

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

ma chiedo se esiste un metodo di libreria predefinito.

risposta

10

Dipende da come si desidera combinarli

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) 

Se si desidera combinare i T s, è possibile utilizzare Foldable.combineAll che utilizza una Monoid[T] (ciò che è validatedValue nella tua domanda?):

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

Se si desidera ottenere un ValidationNel[String, List[T]], è possibile utilizzare 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))) 

Se non ti interessa il risultato, che sembra essere il caso, è possibile utilizzare 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

Mi dispiace, 's' nella domanda originale (ora' validatedValue') è un valore che viene validato, ad esempio 'T'. – Tvaroh

+0

Sembra che 'combineAll' è ciò di cui ho bisogno. Avevo bisogno di aggiungere la chiamata '.toList' al mio' Seq', btw. – Tvaroh

+0

@Tvaroh Sì, i gatti non ha istanze di classe tipo per 'Seq', quindi è necessario andare su' List' o 'Vector'. –