Scalaz validation: cumulative errors or return of any success

How can this behavior be realized with a tale:

"Fail1".failNel[Int] and "Fail2".failNel[Int] to Failure("Fail1", "Fail2") "Fail1".failNel[Int] and 100.successNel[String] to Success(100) 

My solution looks complicated and I think there is another way to do this succint:

  def aggregateErrorsOrSuccess(v1: ValidationNEL[String, Int], v2: ValidationNEL[String, Int]) = { v2.fold( nl => (nl.fail[Int] |@| v1) {(i1, i2) => (/*actually should never happen*/)}, res => res.successNel[String] ) } 

=======================

My second solution:

 implicit def nel2list[T](nl: NonEmptyList[T]) = nl.head :: nl.tail; implicit def ValidationNELPlus[X]: Plus[({type λ[α]=ValidationNEL[X, α]})#λ] = new Plus[({type λ[α]=ValidationNEL[X, α]})#λ] { def plus[A](a1: ValidationNEL[X, A], a2: => ValidationNEL[X, A]) = a1 match { case Success(_) => a1 case Failure(f1) => a2 match { case Success(_) => a2 case Failure(f2) => (f1 <::: f2).fail[A] } } } 

Use it as follows:

 val sum = v1 <+> v2 
+6
source share
1 answer

In fact, you can use the >>*<< (emergency exit?) Method defined in Validation , which is close to your second solution. However, he will also try to combine success, you can customize it.

 def >>*<<[EE >: E: Semigroup, AA >: A: Semigroup](x: Validation[EE, AA]): Validation[EE, AA] = (this, x) match { case (Success(a1), Success(a2)) => Success((a1: AA) ⊹ a2) case (Success(a1), Failure(_)) => Success(a1) case (Failure(_), Success(a2)) => Success(a2) case (Failure(e1), Failure(e2)) => Failure((e1: EE) ⊹ e2) } 
+6
source

Source: https://habr.com/ru/post/907953/


All Articles