Scala - Operators
Left Associative vs Right Associative
- Left:
a op b
=a.op(b)
- Right:
a op b
=b.op(a)
All:
-ending operators are right associative
Operators
->
: Create Tuple2
scala> val a = 1 -> 2
a: (Int, Int) = (1,2)
scala> val b = Tuple2(1,2)
b: (Int, Int) = (1,2)
scala> a == b
res30: Boolean = true
Create key-value pairs for Map
scala> Map(1 -> 2, 3 -> 4)
res32: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
_*
arbitrary long sequences; vararg expansion
<:
: upper type bound
T <: A declares that type variable T refers to a subtype of type A
<%
: view bound
>:
: lower bound
The term T >: A expresses that the type parameter T or the abstract type T refer to a supertype of type A.
+T
declares type T to be used only in covariant positions.
-T
declare T to be used only in contravariant positions.
+:
prepend(elem+:list) right-associative
scala> 1 +: List(1,2)
res21: List[Int] = List(1, 1, 2)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => (b+:a))
res57: List[Int] = List(5, 4, 3, 2, 1)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => b :: a).reverse
res45: List[Int] = List(1, 2, 3, 4, 5)
scala> (1 to 5) filter {_%2 == 0}
res46: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)
:+
append(list:+elem)
scala> List(1,2) :+ 3
res23: List[Int] = List(1, 2, 3)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => (a:+b))
res54: List[Int] = List(1, 2, 3, 4, 5)
scala> 1 +: List(2,3,4) :+ 5
res7: List[Int] = List(1, 2, 3, 4, 5)
::
prepend an element to a list(elem::list) right-associative
scala> 1 :: List(2,3)
res18: List[Int] = List(1, 2, 3)
scala> List(2,3).::(1)
res19: List[Int] = List(1, 2, 3)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => b :: a)
res25: List[Int] = List(5, 4, 3, 2, 1)
::
, +::
: corollary operations
:::
vs ++
: concatenate 2 Lists
scala> (1 to 5).toList ::: (6 to 10).toList
res67: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val x = List(1, 2)
x: List[Int] = List(1, 2)
scala> val y = List(3, 4)
y: List[Int] = List(3, 4)
The two operators are equivalent if used as operators
scala> x ++ y
res9: List[Int] = List(1, 2, 3, 4)
scala> x ::: y
res10: List[Int] = List(1, 2, 3, 4)
However if used as method calls, they are different
scala> x.++(y)
res8: List[Int] = List(1, 2, 3, 4)
scala> x.:::(y)
res11: List[Int] = List(3, 4, 1, 2)
++
vs ++:
++
: left operand determines the type of the resulting collection++:
: right operand determines the type of the resulting collection
scala> val x = List(1, 2)
x: List[Int] = List(1, 2)
scala> val y = scala.collection.mutable.LinkedList(3,4)
y: scala.collection.mutable.LinkedList[Int] = LinkedList(3, 4)
scala> x ++ y
res15: List[Int] = List(1, 2, 3, 4)
scala> x ++: y
res16: scala.collection.mutable.LinkedList[Int] = LinkedList(1, 2, 3, 4)
More Examples
scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)
scala> val b = Array(4,5,6)
b: Array[Int] = Array(4, 5, 6)
scala> a ++ b
res1: Array[Int] = Array(1, 2, 3, 4, 5, 6)
scala> a :+ b
res2: Array[Any] = Array(1, 2, 3, Array(4, 5, 6))
scala> a +: b
res3: Array[Any] = Array(Array(1, 2, 3), 4, 5, 6)
::
prepend an element to a list(elem::list)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => b :: a)
res25: List[Int] = List(5, 4, 3, 2, 1)
:+
append(list:+elem)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => (a:+b))
res54: List[Int] = List(1, 2, 3, 4, 5)
+:
prepend(elem+:list)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => (b+:a))
res57: List[Int] = List(5, 4, 3, 2, 1)
scala> (1 to 5).foldLeft(List[Int]())((a, b) => b :: a).reverse
res45: List[Int] = List(1, 2, 3, 4, 5)
scala> (1 to 5) filter {_%2 == 0}
res46: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)
:::
concatenate 2 Lists
scala> (1 to 5).toList ::: (6 to 10).toList
res67: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)