如何展平一系列猫的ValidatedNel值

Tva*_*roh 12 scala scala-cats

我需要将一系列cats.data.ValidatedNel[E, T]值展平为单个ValidatedNel值:

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

val flattenedResult: cats.data.ValidatedNel[E, T]
Run Code Online (Sandbox Code Playgroud)

我可以这样做:

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

results.reduce(_ |@| _ map { case _ => validatedValue })
Run Code Online (Sandbox Code Playgroud)

但是想知道是否存在预定义的库方法.

Pet*_*ens 17

这取决于你想如何组合它们(validatedValue你的问题是什么?)

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)
Run Code Online (Sandbox Code Playgroud)

如果要组合Ts,可以使用Foldable.combineAll哪个使用Monoid[T]:

val valSum1 = validations1.combineAll 
// Valid(6)
val valSum2 = validations2.combineAll 
// Invalid(OneAnd(kaboom,List(boom)))
Run Code Online (Sandbox Code Playgroud)

如果你想获得ValidationNel[String, List[T]],你可以使用Traverse.sequence:

val valList1: ValidatedNel[String, List[Int]] = validations1.sequence
// Valid(List(1, 2, 3))
val valList2: ValidatedNel[String, List[Int]] = validations2.sequence
// Invalid(OneAnd(kaboom,List(boom)))
Run Code Online (Sandbox Code Playgroud)

如果您不关心结果,似乎就是这种情况,您可以使用Foldable.sequence_.

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

validations1.sequence_.as(validatedValue) // as(x) is equal to map(_ => x)
Run Code Online (Sandbox Code Playgroud)

  • 看起来`combineAll`是我需要的。我需要在我的`Seq`上添加`.toList`调用,顺便说一句。 (2认同)