Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Kotlin, how do you declare a data class with zero constructor parameters?

Tags:

kotlin

Say I want to declare a simple algebraic datatype for integer lists:

sealed class IntList
data class Cons(val head: Int, val tail: IntList): IntList()
data class Nil() : IntList()

However, the last declaration results in an error

Data class must have at least one primary constructor parameter

  1. Why is this limitation present? Looking at the documentation, there seems to be no good technical reasons for requiring data class constructors to be non-nullary.
  2. Is it possible to express nullary constructors without having to write lots of boilerplate code? If I change the last declaration to something like

    sealed class Nil() : IntList()
    

    then I lose the free implementations of hashCode() and equals() that come for free with data class declarations.

EDIT

Alex Filatov gave a nice short solution below. Obviously, you never need more than one instance of Nil, so we can just define a singleton object

object Nil : IntList()

However, what would we do if our lists were parameterized by a type parameter? That is, now the first two lines of our definition would be

sealed class List<A>
data class Cons<A>(val head: A, val tail: List<A>): List<A>()

We cannot declare a polymorphic singleton Nil object which derives from List<A> for any A, since we have to provide a concrete type for A at the time of declaration. The solution (taken from this post) is to declare A as a covariant type parameter and declare Nil as a subtype of List<Nothing> as follows:

sealed class List<out A>
data class Cons<A>(val head: A, val tail: List<A>): List<A>()
object Nil : List<Nothing>()

This allows us to write

val xs: List<Int> = Cons(1, Cons(2, Nil))
val ys: List<Char> = Cons('a', Cons('b', Nil))
like image 641
Ulrik Rasmussen Avatar asked Sep 11 '17 09:09

Ulrik Rasmussen


1 Answers

Because data class without data doesn't make sense. Use object for singletons:

object Nil : IntList()
like image 87
Alex Filatov Avatar answered Nov 14 '22 07:11

Alex Filatov