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

Let's say I want to declare a simple algebraic data type for entire lists:

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

However, the last announcement results in an error

A data class must have at least one primary constructor parameter

  • Why is this limitation present? If you look at the documentation, there are apparently no good technical reasons for requiring the data class constructors to be non-null.
  • Is it possible to express constructors with a zero value without the need to write many patterns? If I change the last ad to something like

     sealed class Nil() : IntList() 

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

EDIT

Alex Filatov gave a short short decision below. Obviously, you don't 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 will 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 is obtained from List<A> for any A , since we must provide a specific type for A at the time of declaration. The solution (taken from this post ) is to declare A as a parameter of the covariant type 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>() 

It allows us to write

 val xs: List<Int> = Cons(1, Cons(2, Nil)) val ys: List<Char> = Cons('a', Cons('b', Nil)) 
+7
kotlin
source share
3 answers

Because a data class without data does not make sense. Use object for single numbers:

 object Nil : IntList() 
+10
source share

You will need to create a regular class

 class Nil : IntList() 

and implement hashCode() and equals() yourself.

A borderless data class makes no sense, because its task is to represent the data.


Or: You can use an object class (like Alex Filatov ), which is the only instance class. Since you do not need state for each individual Nil instance, they can share one.

0
source share

If you really need uniformity in the source code, you can use the default value for the smallest data type.

 data class Nil(val _u: Byte = 0) : IntList() 

or

 data class Nil(val _u: Nothing? = null) : IntList() 
-2
source share

All Articles