Scala: is there a constructor that distinguishes between an applicable and an implicit parameter?

I have a class like this:

class A(arg: Int)(implicit i: Boolean) {
  def apply(v: Double): this.type = {
    // do stuff
    this
  }
}

and I want to instantiate it by doing initialization and calling on the same line:

implicit val i = false
val a = A(arg=1)(v=2.0) // doesn't work
val a2 = (A(arg=1))(v=2.0) // doesn't work

Unfortunately, the compiler assumes that v = 2.0 is for the implicit parameter, not for apply (). I tried several different syntax with insert {} and (), but none of them worked. I understand that v can be moved to the constructor, but in my case this is not an option, because A is subclassed, and I do not want to add v to each constructor of the subclass. Is there any way to achieve this? Thank.

+3
source share
2 answers

How about "ugly but it looks like it works" ...

class A(arg: Int)(implicit i: Boolean) {
  def apply(v: Double): this.type = this
}
implicit val i = false
// removing the :A makes this fail to run on simplyscala
val a1 = (new A(arg=1) : A)(v=2.0)
// also works with explicit method name
val a2 = new A(arg=1).apply(v=2.0)
// and works without implicit being ... implicitized
val a = new A(arg=1)(i)(v=2.0)

, :-) , :

val a = (new A(arg=1))(2.0)
error: type mismatch;
 found   : Double(2.0)
 required: Boolean
       val a = (new A(arg=1))(2.0)

!

.

+5

( , , new A.)

, :

val atmp = A(1)
val a = atmp(2.0)

... , , , .

val a = A(1)(implicitly)(2.0)

. , - apply:

val a = A(1).apply(2.0)

, , :

object A {
  def apply(arg: Int, v: Double)(implicit i: Boolean) = A(arg)(i)(v)
}

val a = A(1, 2.0)
+4

All Articles