Scala: method\operator overloading
scala
Solution
In Scala, any construct of the type `+x`, `-x`, `~x` and `!x` is transformed into a method call `x.unary_+`, etc. This is partially to allow Java-like syntax of having `!b` as the negation of the boolean `b`, or `-x` as the negation of the number `x`.
Therefore, the code snippet `+(new Rational(that, 1))` is translated into `(new Rational(that,1)).unary_+`, and as `Rational` doesn't have this method, you get a compile error. You will get this error only if your function is called `+`, `-`, `~` or `!` as these are the only characters Scala allows as unary operators. For example, if you called your function `@+`, the code compiles just fine.
Though, I would suggest writing the overridden add function as:
def +(that: Int): Rational =
this + (new Rational(that, 1))
This code shows the intent of your function better -- you add a new `Rational` constructed from an integer as a numerator and `1` as denominator to `this`. This way of writing gets translated into `this.+(new Rational(that, 1))`, which is what you want -- invoking the `+` function on `this`.
Note that you can use the infix notation however the function is called. For example, if you change the name back to `add`, you can still keep the definition as:
def add(that: Int): Rational =
this add (new Rational(that, 1))
Problem
The following example is from the book 'Programming in Scala'. Given a class 'Rational' and the following method definition: ``` def add(that: Rational): Rational = new Rational( this.numer * that.denom + that.numer * this.denom, this.denom * that.denom ) ``` I can successfully overload the add method with a convenience version that takes an Int argument, and makes use of the definition above: ``` def add(that: Int): Rational = add(new Rational(that, 1)) ``` No problems so far. Now, if I change the method name to an operator style name: ``` def +(that: Rational): Rational = new Rational( this.numer * that.denom + that.numer * this.denom, this.denom * that.denom ) ``` And overload like so: ``` def +(that: Int): Rational = +(new Rational(that, 1)) ``` I get the following compile error: ``` (fragment of Rational.scala):19: error: value unary_+ is not a member of this.Rational +(new Rational(that, 1)) ^ ``` Why is the compiler looking for a unary version of the `+` method?