In Scala, we have by-name parameters where we can write
def foo[T](f: => T):T = { f // invokes f } // use as: foo(println("hello"))
Now I want to do the same with an array of methods, i.e. I want to use them as:
def foo[T](f:Array[ => T]):T = { // does not work f(0) // invokes f(0) // does not work } foo(println("hi"), println("hello")) // does not work
Is there a way to do what I want? The best I came up with is:
def foo[T](f:() => T *):T = { f(0)() // invokes f(0) } // use as: foo(() => println("hi"), () => println("hello"))
or
def foo[T](f:Array[() => T]):T = { f(0)() // invokes f(0) } // use as: foo(Array(() => println("hi"), () => println("hello")))
EDIT: The proposed SIP-24 is not very useful, as Seth Tisue pointed out in a comment on this answer .
An example where this will be problematic is the following trycatch utility function trycatch :
type unitToT[T] = ()=>T def trycatch[T](list:unitToT[T] *):T = list.size match { case i if i > 1 => try list.head() catch { case t:Any => trycatch(list.tail: _*) } case 1 => list(0)() case _ => throw new Exception("call list must be non-empty") }
Here trycatch takes a list of methods of type ()=>T and sequentially applies each element until it succeeds or the end is reached.
Now suppose I have two methods:
def getYahooRate(currencyA:String, currencyB:String):Double = ???
and
def getGoogleRate(currencyA:String, currencyB:String):Double = ???
which convert one unit currencyA to currencyB and output Double .
I use trycatch as:
val usdEuroRate = trycatch(() => getYahooRate("USD", "EUR"), () => getGoogleRate("USD", "EUR"))
I would prefer:
val usdEuroRate = trycatch(getYahooRate("USD", "EUR"), getGoogleRate("USD", "EUR")) // does not work
In the above example, I would like getGoogleRate("USD", "EUR") called only if getYahooRate("USD", "EUR") throws an exception. This is not the intended behavior of SIP-24.