web-dev-qa-db-ja.com

猫のValidatedNel値のシーケンスをフラット化する方法

一連のcats.data.ValidatedNel[E, T]値を単一の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 })

しかし、事前定義されたライブラリメソッドが存在するかどうか疑問に思います。

15
Tvaroh

それはあなたがそれらをどのように組み合わせたいかによります(あなたの質問の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)

Tsを組み合わせたい場合は、Foldable.combineAllを使用するMonoid[T]を使用できます。

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

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)))

結果を気にしない場合は、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)
17
Peter Neyens