Consider we have 3 validation functions, f1(), f2() and f3(), with each returning Try[A].
Now we would like to call a specific function g() if all three validations are success. def f1(i: Int): Try[Int] = if(i % 2 == 0) Success(i) else Failure(new Exception("Not divisible by 2")) def f2(i: Int): Try[Int] = if(i % 3 == 0) Success(i) else Failure(new Exception("Not divisible by 3")) def f3(i: Int): Try[Int] = if(i % 5 == 0) Success(i) else Failure(new Exception("Not divisible by 5")) def g(i: Int): Int = i * i
Traditional way of doing this is :
val x = 30 f1(x) match { case Success(_) => f2(x) match { case Success(_) => f3(x) match { case Success(_) => g(x) case Failure(ex) => println(ex.getMessage) } case Failure(ex) => println(ex.getMessage) } case Failure(ex) => println(ex.getMessage) }
Though above code is readable but not scalable, meaning the nesting goes on as number of validations increases. Repeating such recurring pattern is not a good design too.
Below is the code snippet that addresses this issue. We shall take the advantage of implicit class feature of scala. implicit class ExtendedTry[A](val x: Try[A]) extends AnyVal { def andElse[B >: A](y: => Try[B]): Try[B] = if (x.isSuccess) y else x } f1(x) andElse f2(x) andElse f3(x) match { case Success(_) => g(x) case Failure(ex) => println(ex.getMessage) }
0 Comments
|
Archives
October 2016
Categories
All
|