score:1

If you define a semigroup instance for Int, you can just add the validations together to get back one Task[ValidationNel[Throwable,Int]]:

  val sum2 = for {
    three ← val3
    four ← val4
  } yield three +|+ four

score:2

You are probably looking for way to accumulate errors or compute result. You may be interested in macculkin operator, I mean a pipe at pipe or |@| (choose the name you like most) ;)

Example of usage. See how errors are accumulated (OMG! and Holly mum! are included in result.

import scalaz._
import Scalaz._

val v1: ValidationNel[Throwable, Int] = 1.successNel
val v2: ValidationNel[Throwable, Int] = new RuntimeException("OMG!").failNel
val v3: ValidationNel[Throwable, Int] = new RuntimeException("Holly mom!").failNel

val sum : ValidationNel[Throwable, Int] = (v1 |@| v2 |@| v3 ) (_ + _ + _)
//scala> sum: scalaz.ValidationNel[Throwable,Int] = Failure(NonEmptyList(java.lang.RuntimeException: OMG!, java.lang.RuntimeException: Holly mom!))

The often made mistake is when you choose to use for comprehension or map functions. When you decide follow such way you will not able to acumulate errors. Only OMG! is accumulated. See below:

for( val1 <- v1;
     val2 <- v2;
     val3 <- v3
    ) yield(val1 + val2 + val3)

//res0: scalaz.Validation[scalaz.NonEmptyList[Throwable],Int] = Failure(NonEmptyList(java.lang.RuntimeException: OMG!))

Related Query

More Query from same tag