Not that I'm banging the same drum again but...
A solution for the problem where we have a number of processes which may produce a successful output, or fail with some error message. The goal is to aggregate the successful outcomes, if all processes produce a success and if one or more fails, to aggregate all error messages.
This can be solved by scalaz validation: firstly, setup some imports
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
Now let's define our "processes"
scala> def fooI(s : String) : ValidationNEL[Exception, Int] = s.parseInt.liftFailNel
fooI: (s: String)scalaz.Scalaz.ValidationNEL[Exception,Int]
scala> def fooF(s : String) : ValidationNEL[Exception, Float] = s.parseFloat.liftFailNel
fooF: (s: String)scalaz.Scalaz.ValidationNEL[Exception,Float]
scala> def fooB(s : String) : ValidationNEL[Exception, Boolean] = s.parseBoolean.liftFailNel
fooB: (s: String)scalaz.Scalaz.ValidationNEL[Exception,Boolean]
Now use Applicative
to aggregate the failures/successes:
scala> def attempt(ss : String*) = (fooI(ss(0)) <|**|> (fooF(ss(1)), fooB(ss(2)))) match {
| case Success((i, f, b)) => println("Found " + i + " " + f + " " + b)
| case Failure(es) => es foreach println
| }
attempt: (ss: String*)Unit
Now let's try for some failures:
scala> attempt("a", "b", "true")
java.lang.NumberFormatException: For input string: "a"
java.lang.NumberFormatException: For input string: "b"
Now let's try for success:
scala> attempt("1", "2.3", "false")
Found 1 2.3 false