Denis
Denis

Reputation: 3707

How to override predefined function in Scala?

I need to implement function to. I have the following working code:

object Main {

  val m = 0
  val km = 1

  implicit def wrapM(v: Int) = new {
    def m = v
  }

  implicit def wrapKm(v: Int) = new {
    def km = v * 1000
  }

  implicit class toWrap(fromVal: Int) {
    def too (value: Int): Double = {
      if (value.equals(km)) {
        fromVal / 1000.0
      } else {
        0
      }
    }
  }

  def main(args:Array[String])
  {
    println(53.m too km)
  }
}

But there is one problem. I use too name, instead of to. If I rename it to to, then I get the error:

Error:(30, 16) type mismatch;
 found   : Int
 required: ?{def to(x$1: ? >: Int): ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method intWrapper in class LowPriorityImplicits of type (x: Int)scala.runtime.RichInt
 and method toWrap in object Main of type (fromVal: Int)Main.toWrap
 are possible conversion functions from Int to ?{def to(x$1: ? >: Int): ?}
    println(53.m to km)
               ^

It is due to the fact, that there is one other function to - scala.runtime.RichInt#to.

Upvotes: 3

Views: 344

Answers (1)

vvg
vvg

Reputation: 6385

Scala does not allow define two implicits with same arguments set in one context....

But there is a way. You should work with different type in toWrap implicit , instead of standard scala Int.

Check sample below. My idea is to implement method to for some wrapper class IntWrap instead of standard Int

 case class IntWrap(v: Int)  {

  }

  val m = 0
  val km = 1

  implicit def wrapM(v: Int) = new {
    def m = IntWrap(v)
  }

  implicit def wrapKm(v: Int) = new {
    def km = v * 1000
  }

  implicit class toWrap(fromVal: IntWrap) {
    def to(value: Int): Double = {
      if (value.equals(km)) {
        fromVal.v / 1000.0
      } else {
        0
      }
    }
  }

  def main(args:Array[String])
  {

    println(53.m to km)
  }

Upvotes: 3

Related Questions