I like Rex's answer, but your question raises so many things, I would like to expand it to add:
- Using the Scala Option / Some / None classes to clarify what should be returned if no match is found. Your example returned null, Rex threw an exception. When using the option, it immediately becomes clear that we will return a match or "No".
- Use type parameters, so you do not need to work only with functions that return a string.
Here is the code:
object A extends App { def getFirstNNWithOption[T](fs: List[() => Option[T]]): Option[T] = fs .view //allows us to evaluate your functions lazily: only evaluate as many as it takes to find a match .flatMap(_()) //invoke the function, discarding results that return None .headOption // take the first element from the view - returns None if empty def f1 = { println("f1"); None } def f2 = Some("yay!") def f3 = { println("f2"); None } println(getFirstNNWithOption(List(f1 _, f2 _, f3 _))) }
Note that when this code works, f2 never prints, demonstrating that by calling .view we evaluate the minimum number of functions before returning a match.
Note that the calling calls to this method should now take into account the fact that a match cannot be found: instead of returning T, we return Option [T]. In our case above, this will return Some ("yay"). When all functions return None, the return value will be None. No more NullPointerExceptions when you accept null for an actual match!
source share