Search code examples
scalascalaz

Scalaz fail slow using ValidationNel


I am learning Scala and today came across the Fail Slow mechanism using Scalaz ValidationNel however it is really difficult to understand how to use it. I am reading these blogs: Blog1 , I am reading this StackOverflow post too: StackOverflow but it is really difficult to understand for non functional programmer. Can somebody provide a simple example on how to accumulate errors in ValidationNel in Scala? It will be really helpful to have a description about the example too.


Solution

  • Using the example from the blog you've linked

    val sumV: ValidationNEL[String, Int] = for {
      a <- 42.successNel[String]
      b <- "Boo".failNel[Int]
      c <- "Wah wah".failNel[Int] // by defn of flatMap, can't get here
    } yield a + b + c
    

    What this is doing is using a flatMap to chain together various operations. 42.successNel[String], for example, creates a Success, and "Boo".failNel[Int] creates a failure. The way flatMap works here is to continue on to the next operations only on a success. So this is a "fail fast" operation - it gathers the first failure into your error case and stops.

    If you want to "fail slow" - ie. gather all possible failures, you need to use a different method. This is where Applicative comes in.

    val yes = 3.14.successNel[String]
    val doh = "Error".failNel[Double]
    
    def addTwo(x: Double, y: Double) = x + y
    
    (yes |@| yes)(addTwo) // Success(6.28)
    (doh |@| doh)(addTwo) // Failure(NonEmptyList(Error, Error))
    

    (a |@| b)(someFunctionOfTwoArgsHere) - What this is saying is "Perform the 'a' operation, and perform the 'b' operation, and if both are successful, perform someFunctionOfTwoArgsHere(a,b). Otherwise, take any failures and combine them. So if a fails, but b succeeds, you get a Validation failure with the result of a failing. If a AND b fails, you get a Validation failure with the results of both a and b failing.