Ambiguous overloading: fix it or try something else?

103 Views Asked by At

Background: I'm working on using scala.js/scalatags together with scala.rx. What I'm trying to achieve is binding values from html inputs to Rx Vars, using operator style. Here's what I'm up to:

implicit class BoundHtmlInput(input: Input) {
  def bindTextTo(v: Var[String]): Input = {
    input.oninput = { (e: dom.Event) => v() = input.value}
    input
  }

  def bindNumberTo(v: Var[Int]): Input = {
    input.oninput = {(e: dom.Event) => v() = input.valueAsNumber}
    input
  }

  def ~>[T](v: Var[T])(implicit ev: T =:= Int): Input =
     bindNumberTo(v.asInstanceOf[Var[Int]])

  def ~>[T](v: Var[T])(implicit ev: T =:= String): Input = 
     bindTextTo(v.asInstanceOf[Var[String]])
}

It works fine for the method calls, but fails for operator ~> call. The error is following:

Error:(43, 70) ambiguous reference to overloaded definition,
both method ~> in class BoundHtmlInput of type [T](v: rx.Var[T])(implicit ev: =:=[T,String])org.scalajs.dom.html.Input
and  method ~> in class BoundHtmlInput of type [T](v: rx.Var[T])(implicit ev: =:=[T,Int])org.scalajs.dom.html.Input
match argument types (rx.core.Var[String])

And I'm not happy about the usage of asInstanceOf either.

I hope this provides enough context. My question is, what is the better way to achieve what I want?

1

There are 1 best solutions below

0
sjrd On BEST ANSWER

Use Var[Int] and Var[String] directly, with dummy implicits to fight off double-def-after-erasure:

def ~>[T](v: Var[Int]): Input =
  bindNumberTo(v)

def ~>[T](v: Var[String])(implicit dummy: DummyImplicit): Input = 
  bindTextTo(v)

You can add as many DummyImplicits as necessary, if you have more types to deal with:

def ~>[T](v: Var[Boolean])(implicit dummy1: DummyImplicit,
    dummy2: DummyImplicit): Input = 
  bindBooleanTo(v)