Reputation: 3076
Is it possible to modify the precedence of any self-defined operators? For example, I implement elementary arithmetic with totally self-defined operators.
case class Memory(name:String){
var num:Num = null
def <<=(x:Num): Unit = {
println(s"assign ${x.value}")
this.num = x
}
}
case class Num(var value:Int) {
def +|+(x:Num) = {
println("%d + %d = %d".format( value,x.value,x.value + value ))
Num(value + x.value)
}
def *|*(x:Num) = {
println("%d * %d = %d".format( value,x.value,x.value * value ))
Num(value * x.value)
}
}
val m1 = Memory("R")
val a = Num(1)
val b = Num(3)
val c = Num(9)
val d = Num(12)
m1 <<= a *|* b +|+ c +|+ d *|* a
println("final m1 ",m1.num.value)
The results are
1 * 3 = 3
3 + 9 = 12
12 * 1 = 12
12 + 12 = 24
assign 24
(final m1 ,24)
Apparently the precedence is correct. I want *|*
be the same precedence as *
and +|+
the same as +
, <<=
is equivalent as =
as well. How scala figure it out?
Upvotes: 2
Views: 696
Reputation: 8427
Answering the question about modyfing operator precedence - to change it you basically just have to change the first character of your custom operator - this is how scala figures out precedense for infix operators, by just looking at the first character. So if you eg. add an operator *|+
:
*|*
, like with *
and *
.+|+
, just like with *
and +
.Unfortunately there is no other way to deal with it right now. No custom annotations/weights and so on to avoid making reading code too fuzzy.
The precedence rules are very well summarized here - Operator precedence in Scala.
About your issue though - you get the right results.
*|*
, as well as *
are left-associative operators and their first character is *
, so they have equal precedense.
Your operation:
a *|* b +|+ c +|+ d *|* a
Translates to
a * b + c + d * a
, which is 1 * 3 + 9 + 12 * 1
.
Applying standard precedence rules - (a*b) + c + (d*a)
result is 24.
Upvotes: 1