Reputation: 1374
Alright, Scala has me feeling pretty dense. I'm finding the docs pretty impenetrable -- and worse, you can't Google the term "Scala ++:" because Google drops the operator terms!
I was reading some code and saw this line:
Seq(file) ++: children.flatMap(walkTree(_))
But couldn't figure it out. The docs for Seq
show three things:
++
++:
++:
Where the latter two are over loaded to do.. something. The actual explanation in the doc says that they do the same thing as ++
. Namely, add one list to another.
So, what exactly is the difference between the operators..?
Upvotes: 5
Views: 4310
Reputation: 1997
Just to make sure:
A colon (:) in the end of a method name makes the call upside-down.
Let's make two methods and see what's gonna happen:
object Test {
def ~(i: Int) = null
def ~:(i: Int) = null //putting ":" in the tail!
this ~ 1 //compiled
1 ~: this //compiled
this.~(1) //compiled
this.~:(1) //compiled.. lol
this ~: 1 //error
1 ~ this //error
}
So, in seq1 ++: seq2
, ++:
is actually the seq2
's method.
edited: As @okiharaherbst mentions, this is called as right associativity.
Upvotes: 5
Reputation: 5428
Scala function naming will look cryptic unless you learn a few simple rules and their precedence.
In this case, a colon means that the function has right associativity as opposed to the more usual left associativity that you see in imperative languages.
So ++:
as in List(10) ++: Vector(10)
is not an operator on the list but a function called on the vector even if it appears on its left hand-side, i.e., it is the same as Vector(10).++:(List(10))
and returns a vector.
++
as in List(10) ++ Vector(10)
is now function called on the list (left associativity), i.e., it is the same as List(10).++(Vector(10))
and returns a list.
Upvotes: 1
Reputation: 13667
++
and ++:
return different results when the operands are different types of collection. ++
returns the same collection type as the left side, and ++:
returns the same collection type as the right side:
scala> List(5) ++ Vector(5)
res2: List[Int] = List(5, 5)
scala> List(5) ++: Vector(5)
res3: scala.collection.immutable.Vector[Int] = Vector(5, 5)
There are two overloaded versions of ++:
solely for implementation reasons. ++:
needs to be able to take any TraversableOnce
, but an overloaded version is provided for Traversable
(a subtype of TraversableOnce
) for efficiency.
Upvotes: 15
Reputation: 1323953
what exactly is the difference between the operators..?
The kind of list a Seq.++
operates on.
def ++[B](that: GenTraversableOnce[B]): Seq[B]
def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Seq[A], B, That]): That
def ++:[B](that: TraversableOnce[B]): Seq[B]
As commented in "What is the basic collection type in Scala?"
Traversable
extends TraversableOnce
(which unites Iterator
and Traversable
), and TraversableOnce
extends GenTraversableOnce
(which units the sequential collections and the parallel.) Upvotes: 0