The empty list collection.
The goal of this project is to open the discussion on the potential addition of an empty list collection to the standard library. This is a counter proposal to the idea of a non empty list that has been discussed repetitively for the collection strawman.
Try is out from sbt:
"in.nvilla" %% "empty-list" % "1.0" // use %%% for Scala.js
The empty list collection is defined as follows:
trait EmptyList[+T] extends Product with Serializable
final case object EmptyList extends EmptyList[Nothing]
The library also provides useful shorthands for the EmptyList
type and value:
type EL[+T] = EmptyList[T]
val EL = EmptyList
A separate artifact with cats' type class instances for EmptyList
is published as empty-list-cats
.
The empty-list project and contributors support the Empty Code of Conduct and want all its associated channels (e.g. GitHub, Gitter) to be a safe and friendly environment for everyone.
-
scala.collection.immutable.Nil
defines unsafe operation such ashead
andtail
.EmptyList
doesn't.EmptyList
is simply a better type to indicate emptiness!scala> Nil.head java.util.NoSuchElementException: head of empty list at scala.collection.immutable.Nil$.head(List.scala:428) ... 29 elided scala> Nil.tail java.lang.UnsupportedOperationException: tail of empty list at scala.collection.immutable.Nil$.tail(List.scala:430) ... 29 elided
-
scala.collection.immutable.Nil
loses it's emptiness type information as soon as it's used with any operation such asmap
offlatMap
. Thanks to having it's own functor instance,EmptyList
properly propagate type information!scala> Nil.map(identity) res1: List[Nothing] = List()
scala> EL.map(identity) res2: EmptyList.type
-
scala.collection.immutable.Nil
has unhygienic equality, it can be compared to anything without scalac emitting any warning.Nil
is also (surprisingly) equal to other empty collections that inheritscala.collection.GenSeq[_]
:scala> Nil == Vector.empty res3: Boolean = true
EmptyList
is a proper algebraic data type, things always work as expected:scala> EL == Vector.empty <console>:1: warning: comparing values of types EL and Vector[Nothing] using `==` is always false EL == Vector.empty ^ res4: Boolean = false