Double Definition Error Despite Different Parameter Types

compiler-errors, overloading, scala, types

Solution

Here's a simpler example that shows the same issue:

object Example {
  def foo[T](f: Int => T) = ???
  def foo[T](f: String => T) = ???
}

This is equivalent to the following, after desugaring the `=>` symbols:

object Example {
  def foo[T](f: Function[Int, T]) = ???
  def foo[T](f: Function[String, T]) = ???
}

The problem is that the Java Virtual Machine doesn't know about generics (in either Scala or Java), so it sees these two methods as the following:

object Example {
  def foo[T](f: Function) = ???
  def foo[T](f: Function) = ???
}

Which is clearly a problem.

This is one of many reasons to avoid method overloading in Scala. If that's not an option, you could use a trick like the following:

object Example {
  implicit object `Int => T disambiguator`
  implicit object `String => T disambiguator`

  def foo[T](f: Int => T)(implicit d: `Int => T disambiguator`.type) = ???
  def foo[T](f: String => T)(implicit d: `String => T disambiguator`.type) = ???
}

Which looks the same usage-wise, but is obviously pretty hideous.

Problem

I'm receiving a double definition error on the following two methods: ``` def apply[T](state: T, onRender: T => Graphic, onMouseEvent: (MouseEvent, T) => T): GraphicPanel = apply(state, onRender, onMouseEvent = Some(onMouseEvent)) ``` and ``` def apply[T](state: T, onRender: T => Graphic, onKeyEvent: (KeyEvent, T) => T): GraphicPanel = apply(state, onRender, onKeyEvent = Some(onKeyEvent)) ``` which are both method overloads for the more general `apply` method with the signature: ``` def apply[T](state: T, onRender: T => Graphic, onTickEvent: Option[T => T] = None, fps: Int = 30, onMouseEvent: Option[(MouseEvent, T) => T] = None, onMouseMotionEvent: Option[(MouseEvent, T) => T] = None, onMouseInputEvent: Option[(MouseEvent, T) => T] = None, onKeyEvent: Option[(KeyEvent, T) => T] = None) ``` I would assume that a even though the classes `KeyEvent` and `MouseEvent` have a common superclass (`InputEvent`), the compiler should still be able to distinguish between them. However, it is throwing the error: double definition: method apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, someOnKeyEvent: (java.awt.event.KeyEvent, T) => T)edu.depauw.scales.graphics.GraphicPanel and method apply:[T](state: T, onRender: T => edu.depauw.scales.graphics.Graphic, onMouseEvent: (java.awt.event.MouseEvent, T) => T)edu.depauw.scales.graphics.GraphicPanel at line 115 have same type after erasure: (state: Object, onRender: Function1, someOnKeyEvent: Function2) edu.depauw.scales.graphics.GraphicPanel Anyone have any idea what is going on? Admittedly, I don't know what is meant by the phrase "after erasure", so maybe an explanation of how that works might be helpful.

Original source

Related problems