In Scala, List is implemented as linked list. And it has 2 parts, head and tail. Last cell in List contains Nil.
Nil in Scala is itself a singleton and extends List[Nothing], as documented here
As Nil is a singleton, does it mean end element of all List instances in Scala has same object.
While in fact the end marker is always the singleton Nil, the same object, the last element is the one just before.
scala> val a = 1 :: 2 :: Nil
a: List[Int] = List(1, 2)
scala> a.last
res10: Int = 2
You might argue about the terminology, but coders are often positivists in that regard, and truth is, what the code says.
Yes, all lists end with the empty list known as Nil.
You can see that this is true by trying to create a list without Nil at the end.
val a = 1 :: 2
// fails
val a = 1 :: Nil
// succeeds
val a = scala.collection.immutable.::(1, Nil)
// succeeds
The last case calls the case class constructor for ::
which extends List
, hence, creating a List
.
The code for the case class ::
is...
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
override def tail : List[B] = tl
override def isEmpty: Boolean = false
}
And the operation ::
is defined within the List object, which calls the case class ::
to create a list for you when doing something like 1 :: Nil
.
As seen here:
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
You can also see how the code for the map
operation on List
iterates through the List until reaching Nil.
Snippet taken from map
function in List
class
while (rest ne Nil) {
val nx = new ::(f(rest.head), Nil)
t.tl = nx
t = nx
rest = rest.tail
}
(ne stands for not equal)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With