| :: | prepends a single element to a list. E.g.: 1 :: List(2, 3, 4)List(1, 2, 3, 4) | 
| +: | generalized ::introduced in Scala 2.10. E.g.:val head +: tail = List(1, 2, 3)head: Int = 1; tail: List[Int] = List(2, 3) | 
| :+ | backwards +:. E.g.,val tail :+ head = List(1, 2, 3)tail: List[Int] = List(1, 2); head: Int = 3 | 
| ++ | concatenates two lists. E.g.: List(1, 2) ++ List(3, 4)List(1, 2, 3, 4) | 
| ::: | concatenates two lists. E.g.: List(1, 2) ::: List(3, 4)(which is interpreted asList(3, 4).:::(List(1, 2)))List(1, 2, 3, 4)So, effectively, it’s equivalent to++. | 
| @ | is used in pattern-matching, where you want to capture the entire match as a variable. For example, if you want the head as well as the whole list, so that you can repeat the head at the beginning: List(List(2, 3, 4), List(4, 9, 16)).map { case (lst @ head :: _) => head :: lst }List(List(2, 2, 3, 4), List(4, 4, 9, 16)) | 
| ^^ | connects a Parser match to a post-processing step. For example, """\d+(\.\d*)?""".r ^^ { _.toDouble }parses the regex match as aDouble. | 
| <% | view bound; specifies adherence to a trait (type class). A <% Ordered[A], for example, says that the type parameter you’re using,A, must implement theOrderedtrait, i.e., it must be viewable as anOrdered[A]. | 
| <: | upper type bound; T <: Arequires thatTis a subtype ofA. | 
| >: | lower type bound; B >: Arequires thatBis a supertype ofA.List[+A]#sumis declared asdef sum[B >: A](implicit num: Numeric[B]): B, which says that the returned value B will be a supertype of the list items. The implicit bit is evidence that the returned value will be numeric, which implies that the list’s items of typeAmust be a subtype ofNumeric[B]. This is more complicated than it really ought to be (def sum[A <: Number]: Number) since Scala’s numeric types (e.g.,Int,Double), don’t actually inherit a common type ancestor likeNumber. | 
| =:= | generalized type constraint; A =:= B(a.k.a.,=:=[A, B]) specifies that the typeAmust exactly equal the typeB. Inside a trait/class/whatever with some parameterized typea: A, we could define a methoddef squared(implicit evidence: A =:= Int) = a * a, and then callmy_a.squaredthat would only compile (type check) ifAis preciselyInt. | 
| <:< | generalized type constraint; A <:< B(a.k.a.,<:<[A, B]) specifies thatAmust be a subtype ofB, similar to<:. | 
| <%< | generalized type constraint; A <%< B(a.k.a.,<%<[A, B]) specifies thatAmust be viewable asB, similar to<%(via implicit conversion). | 
[+A] and contravariance [-A]co(ntra)variance is more a property of inheritance than an immediate property of the specific type it is declared on. Suppose we have:
class Animal
class Mammal extends Animal
class Reptile extends Animal
The covariance annotation on collection.immutable.List[+A] means that we can treat the items of a List[Mammal] as instances of Animal. If we add an Animal to a List[Mammal], it would return a new List[Animal]. We could also add a Reptile and have the same effect.
On the other hand, mutable collections like collection.mutable.ListBuffer[A] are not covariant; if they were, we could add an Animal to an existing ListBuffer[Mammal], which is problematic. The collection is mutable, but its type (parameters) are not, so there has to be a stricter restriction on what type of elements the collection can contain.
The contravariance annotation -A in Function1[-A,+B] (a function that takes an A and returns a B) means that wherever we need a function of this type, we can alternatively supply a function that converts A or some supertype of A, to B or some subtype of B.
The following example demonstrates contravariance (not covariance, but covariance can also come into play):
val drawAnimal: Animal => Unit = { animal => println("o~") }
val drawMammal: Mammal => Unit = { mammal => println(":°:") }
val initCanvas = { () => println("---") }
def MammalCanvas(drawFn: Mammal => Unit, mammal: Mammal) = { initCanvas(); drawFn(mammal) }
Now we can call the MammalCanvas function with drawMammal, which doesn’t use contravariance:
MammalCanvas(drawMammal, new Mammal)
---
:°:
Or, since drawFn has the type Function1[-Mammal,+Unit], not Function1[Mammal,+Unit],
we can use contravariance to call it with drawAnimal:
MammalCanvas(drawAnimal, new Mammal)
---
o~
References:
Function[-A1,…,+B] not about allowing any supertypes as parameters?The Scaladoc on performance characteristics is nice.
| Iterable | is the most basic trait of an ordered collection. (It inherits Traversable, butTraversablealso applies to unordered types, likeSetand plainHashMap.) But it doesn’t necessarily tell you the size, let you index, or iterate the collection more than once. | 
| Seq | is the basic trait for indexable ordered collections. Instantiating a Seqcreates aLinearSeq, i.e., aList. | 
| IndexedSeq | is the first of the two principle subtraits of Seq, best suited for random access to elements and determining the size of the sequence.Vectoris the primary implementation.RangeandWrappedStringare special cases ofIndexedSeq, and thus presumably backed byVectorinstances. | 
| LinearSeq | is the second of the two principle subtraits of Seq, better suited for head and tail access.Listis the primary implementation.Stream,Queue, andStackare other collections based onLinearSeq(Stackhas been deprecated). | 
| List | is the most basic actual implementation of LinearSeq, and it’s the default implementation ofTraversable,Iterable,Seq,LinearSeq, and of courseList, meaning you can call any of those as a function, and they’ll all give you back aList.(Unless you’re in mutable-land, in which case Traversable,Iterable, andSeqwill all return anArrayBuffer, whileLinearSeqwill return aMutableList. There is nomutable.List.)Apparently Listis most similar to Java’sLinkedList. | 
| Vector | is the most basic actual implementation of IndexedSeq, and it’s the default implementation ofIndexedSeqandVector, meaning you can call either of those as a function, and they’ll all give you back aVector.(In mutable-land, IndexedSeqreturns anArrayBufferinstead.)Vectoris preferable toListif you’re going to be parallelizing over the collection. | 
| Stream | derives from LinearSeq, but it’s not really a good name, since it memoizes everything that gets evaluated, instead of discarding it. What I generally think of when I hearStreamis closer to theIterablelevel — I thinkLazyListwould be a better name. | 
| mutable.ArrayBuffer | is the Scala equivalent of Java’s ArrayList. It sort of derives fromIndexedSeq, and it’s the mutable version ofVector. It’s best for random access and random writes, less good at prepending and appending. | 
| mutable.Queue | is backed by mutable.MutableList. | 
| mutable.ListBuffer | seems to be the mutable version of List. It’s best for prepend and append operations, less suited for random access or random writes. I’m not sure how it differs frommutable.Queue. | 
SBT fetches dependencies via resolvers.
Handy SBT Plugins:
The sbt-updates plugin compares the dependencies listed in build.sbt to the current version available on Maven Central (or other configured repositories).
To install the plugin for all sbt projects, create a file at ~/.sbt/0.13/plugins/sbt-updates.sbt (the filename can be whatever, I think) with the following line:
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.3.3")
Then at the sbt REPL for your specific project, call:
dependencyUpdates
Show Scala compiler version, e.g., in a REPL:
scala.util.Properties.versionString