Multiple overloaded alternatives of method apply define default arguments

106 views Asked by At

I have the following case class

case class Task[I, O](
    dd: DD,
    parser: CP[I, (O, Option[CE])],
    canonicalize: Boolean,
    opt: Boolean,
    schema: Schema,
    remove: Boolean = false,
    deduplicate: Boolean = false,
    taskId: Option[String] = None
)(implicit
    val ul: UL[O],
    val ael: AEL[O],
    val it: IT[I],
    val ot: TT[O]
)

object Task {
  def apply(
      dd: DD,
      sources: Sources,
      cc: String,
      tc: Option[TC] = None
  )(implicit
      context: PEC
  )
}

and I am getting

multiple overloaded alternatives of method `apply` define default arguments

Obviously, I do not have multiple apply methods here. There's one explicitly defined apply method and another one that is implicitly defined because of the case class. I have to mention that if I remove tc: Option[TC] = None from the apply method in the companion object, the compilation succeeds. I understand the explanation provided here but I do not see how tc: Option[TC] = None is breaking the compilation.

// Edit

Being more explicit about what the compiler generates. For the implicit apply method generated from the case class we will have

apply$default$6:Boolean = false
apply$default$7:Boolean = false
apply$default$8:Option[String] = None

for the explicit apply that I defined it will only create

apply$default$4:Option[TC] = None

At least this is how I understand it. Where is the clash exactly?

1

There are 1 answers

0
Niko On

Scala does not allow the existence of default values in multiple overloaded methods. The position or the data type of the default value does not matter. The fact that one of the methods could be an apply method does not matter either.

This will work

class Foo(a: String, b: String) {
  def apply(c: Int = 3) = new Foo(c.toString, c.toString)

  def other(a: Int = 1, b: String) = println(a, b)
}

This will not work

class Foo(a: String, b: String) {
  def apply(c: Int = 3) = new Foo(c.toString, c.toString)

  def other(a: Int = 1, b: String) = println(a, b)
  def other(a: Int, b: String = "foo", c: Float) = println(a, b, c)
}

This will not work

class Foo(a: String, b: String) {
  def apply(c: Int = 3) = new Foo(c.toString, c.toString)
  def apply(d: Int, e: Int = 100) = new Foo(d.toString, e.toString)

  def other(a: Int, b: String = "foo", c: Float) = println(a, b, c)
}