Alias for empty List

Hi,

Is there any way of creating an alias for an empty list of a particular type, something like:

type EmptyA = List[A]() ?

I’ve tried it by doing:

object EmptyA extends List[A]()

but list is final.

I’m not sure what you’re hoping to achieve. An object representing an empty list already exists: Nil.
You can alias it if you want:

val empty = Nil

// or "specialized" to type A:
val emptyA: List[A] = Nil

Note that Nil is a subtype of List[Nothing]. List is covariant and Nothing is a subtype of every other type. So List[Nothing] is compatible with any other type. 42 :: Nil is a List[Int]. "foo" :: Nil is a List[String]. "foo" :: 42 :: Nil is a List[Any].

If you want a type alias instead I’d go with type EmptyList = List[Nothing]. You cannot have a type alias representing an empty List[A]. You can’t see in the type alone whether a list is empty or not. Except for List[Nothing], because there is no value of type Nothing.

1 Like

Would the call to List.empty[A] work fine for you?

2 Likes

Thanks for the comments. I was thinking about say modelling polynomials where the empty list is Zero - and whether it is possible to rename the empty list to Zero. However, I’m not sure if this could cause confusion between the concept and its representation.

It sounds like you want to distinguish between the empty list and non-empty lists on the type level.

There are three types you want to exist for that, the type of empty lists, the type of non-empty lists, and the type of lists that could be empty or could be non-empty.

In the standard library, the value Nil is the empty list, and its singleton type, Nil.type could be used for the empty list. List[+A] is the type of lists that could be empty or could be non-empty. The type of non-empty lists is ::.

Using them for something sensible tends to be difficult – List doesn’t abstract over its length, so you don’t know whether the tail of some :: is a :: or a Nil.type. In addition, if you know something to be Nil.type at compile time, you know its value is going to be Nil, and you can usually deal with this by not abstracting over it at all, but special-casing the Nil case on the term level.

It’s more common to have a use for the opposite: the non-empty list. It’s also not easy working with that in the stdlib, since :: is really seen as a constructor of List, and all operations that could return :: return List instead. It’s worth noting that the cats library provides a NonEmptyList class.

Another library that may be of interest is shapeless, which does have the mechanisms to abstract over list arity.

1 Like

If polynomials are central to your project, they deserve to be a type on their own. Consider wrapping your Lists into a case class or a value class.

1 Like