Scala: Passing one implicit parameter implicitly and the other explicitly. Is it possible?
All I can add is:
def foo(implicit a: Int, b: String) = println(a, b)
implicit val i1 = 1
implicit val s = ""
val i2 = 2
foo(i2, implicitly[String])
In case your method has many implicit parameters (I sometimes have in my projects) and you sometimes want to just specify one of them explicit and let the others been resolved implicitly you can write implicitly
for every other parameter like showed in my other answer. But sometimes you will change the signature of that method or the explicit parameter is in the middle of that parameter list, then you can make more readable client code with the following construct:
Suppose you have some types and their implicit dummy objects:
trait I1; implicit object I1 extends I1
trait I2; implicit object I2 extends I2
trait I3; implicit object I3 extends I3
trait I4; implicit object I4 extends I4
trait I5; implicit object I5 extends I5
trait I6; implicit object I6 extends I6
Now you have your method foo1
that uses these implicits:
def foo1(implicit i1: I1, i2: I2, i3: I3, i4: I4, i5: I5, i6: I6) {
println(i1, i2, i3, i4, i5, i6)
}
Now you often want to explicitly specify i4: I4
. So you write:
val i4 = new I4 {}
foo1(implicitly, implicitly, implicitly, i4, implicitly, implicitly)
Ugly!
With the following (should be placed in tight scope to method foo2
and perhaps renamed) wrapper for all implicits:
object Implicits {
def apply(i4: I4)(implicit i1: I1, i2: I2, i3: I3, i5: I5, i6: I6) = new Implicits(i1, i2, i3, i4, i5, i6)
implicit def applying(implicit i1: I1, i2: I2, i3: I3, i4: I4, i5: I5, i6: I6) = new Implicits(i1, i2, i3, i4, i5, i6)
}
class Implicits(val i1: I1, val i2: I2, val i3: I3, val i4: I4, val i5: I5, val i6: I6)
and the related method foo2
:
def foo2(implicit implicits: Implicits) = {
import implicits._
println(i1, i2, i3, i4, i5, i6)
}
you can now call foo2
instead of foo1
the following way:
locally {
foo2 // using implicit dummy objects I1, ..., I6 from above
// or with explicit I4:
val i4 = new I4 {}
foo2(Implicits(i4))
}
- Explicitly call
foo(i2, s1)
but you loose the benefit of the use of theimplicit String
- Define
def foo1(a: Int)(implicit b: String)=foo(a,b)
and you callfoo1(i2)