Nil
is basic building block for creating List
as a recursive data structure. List is useful datastructure that provides constant time access O(1) to the head (first element).
List at it's bare minimum core, is built on top of 3 operations
head
, tail
, and isEmpty
. Nil
is singleton sub-class of List
, so it is a special one-of-its-kind instance representing an empty list. The cons operator ::
is defined on List to build a list recursively, by prepending one element in the List.
See the definition of trait List
and object Nil
(highly simplified)
trait List[A] {
def head: A
def tail: List[A]
def isEmpty: Boolean
}
case object Nil extends List[Nothing] {
def head = throw new NoSuchElementException("head of empty list")
def tail = throw new UnsupportedOperationException("tail of empty list")
def isEmpty = true
}
Since any identifier/operator that ends with a :
, associates to the right, ::
operator also associates to the right.
When you write 1::2::3
, scala tries to rewrite this calls as 3.::(2.::(1))
. i.e 3 becomes the receiver of the first invocation of ::
, which doesn't exist on any arbitrary data-type (Int in this case).
This is why, you always build up on an Empty List - Nil. Think of it as prepending each element, one by one over the empty List Nil
.