Nested "if" / "match" expression in scala: better approach?

I have a number of verification functions that return the [Problem] parameter, if any, or No if no verification problems are found. I would like to write a simple function that calls each test function, stops and returns the first no-no result.

Naturally, I can write this method in a "java style", but I would like to know if there is a better approach.

EDIT

This was the original Java solution:

validate01(arg); validate02(arg); validate03(arg); ... 

Each method throws an exception in case of a problem. I would stay away from exceptions while I write Scala.

+4
source share
3 answers

As an example, suppose we want to check a String . Our validation function accepts String and a list of validators, which are functions from String to Option[Problem] . We can implement it as functionally as this:

 def firstProblem(validators: List[String => Option[Problem]], s:String) = validators.view.flatMap(_(s)).headOption 

This creates a new list, applying each check function to the string and saving the result only if it's Some . Then we take the first element of this List. Due to the call to view list will only be computed as needed. So, as soon as the first problem is found, further validators will not be called.

+6
source

If you have a finite and known number of checks at compile time, you can use .orElse on Options:

 def foo(x: Int): Option[Problem] = ... def bar(x: Int): Option[Problem] = ... ... def baz(x: Int): Option[Problem] = ... foo(1) orElse bar(2) orElse .. baz(n) 
+6
source

Perhaps you want - if the validation functions take no arguments

 def firstProblem(fs: (() => Option[Problem])*) = { fs.iterator.map(f => f()).find(_.isDefined).flatten } 

You will receive an existing Option[Problem] , if any, or None if all of them are successful. If you need to pass arguments to functions, you need to explain what these arguments are. For example, you could

 def firstProblem[A](a: A)(fs: (A => Option[Problem])*) = /* TODO */ 

if you can pass the same argument to all of them. You would use it as follows:

 firstProblem(myData)( validatorA, validatorB, validatorC, validatorD ) 
+1
source

All Articles