Scala's '::' operator, how does it work?
From the Spec:
6.12.3 InfixOperations An infix operator can be an arbitrary identifier. Infix operators have precedence and associativity defined as follows.
...
The associativity of an operator is determined by the operator’s last character. Operators ending in a colon ‘:’ are right-associative. All other operators are left- associative.
You can always see how these rules are applied in Scala by printing the program after it has been through the 'typer' phase of the compiler:
scala -Xprint:typer -e "1 :: Nil"
val r: List[Int] = {
<synthetic> val x$1: Int = 1;
immutable.this.Nil.::[Int](x$1)
};
It ends with a :
. And that is the sign, that this function is defined in the class to the right (in List
class here).
So, it's List(Foo(2)).::(Foo(40))
, not Foo(40).::(List(Foo(2)))
in your example.
One aspect missing in the answers given is that to support ::
in pattern matching expressions:
List(1,2) match {
case x :: xs => println(x + " " + xs)
case _ => println("")
}
A class :: is defined :
final case class ::[B](private var hd: B, private[scala] var tl: List[B])
so case ::(x,xs)
would produce the same result. The expression case x :: xs
works because the default extractor ::
is defined for the case class and it can be used infix.