How can I define a function with multiple implicit arguments.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn\'t work
There is another (IMO simpler and more flexible) way to achieve a similar effect:
// Note the implicit is now a Tuple2
def myFun(arg: String)(implicit p: (String, Int) ): Unit = {
println(arg + p._1 + p._2)
/*otherwise your actual code*/
}
// These implicit conversion are able to produce the basic implicit (String,Int) Tuples
implicit def idis(implicit is: String, ii: Int): (String,Int)= (is,ii)
implicit def idi(s: String)(implicit ii: Int): (String,Int)= (s,ii)
// The basic implicit values for both underlying parameters
implicit val iString = " world! "
implicit val iInt = 2019
myFun("Hello")
myFun("Hello")(" my friend! ")
myFun("Hello")(" my friend! ",2020)
// Output is:
// Hello world! 2019
// Hello my friend! 2019
// Hello my friend! 2020
// If we add the following implicit,
implicit def ids(i: Int)(implicit is: String)= (is,i)
// we can even do
myFun("Hello")(2020)
// , and output is:
// Hello world! 2020
Using a Tuple as the underlying representation for the parameters is not a good idea because the implicit conversions could interfere with other uses. Actually, implicit conversions to any standard type (including library ones) usually create trouble in any non-trivial application. The solution is to create a dedicated case class to hold the parameters instead of a Tuple. An important advantage is that they could be given names much more meaningful than _1 and _2.