user3308774
user3308774

Reputation: 1374

What does the ++: operator do to a list?

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

Answers (4)

Ryoichiro Oka
Ryoichiro Oka

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

VH-NZZ
VH-NZZ

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

wingedsubmariner
wingedsubmariner

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

VonC
VonC

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?"

Upvotes: 0

Related Questions