title: Error using an object for implementing an empty List
body: <p>I'm trying to rewrite the List interface as an exercise for learning Functional Programming in Kotlin, but I'm not able to figure out why I'm getting an error when I'm trying to have an object as the empty list, that doesn't occur in the Kotlin standard library. In my code, see below, I want to use NIL as a singleton empty list, using list() as the function to return it. However, this generates a type mismatch error on the function of type "Required List. Found NIL"</p>
  
  <pre><code>interface List&lt;A&gt; {
      val empty: Boolean
      val head: A
      val tail: List&lt;A&gt;
  
      fun cons(a: A): List&lt;A&gt; = Cons(a, this)
  }
  
  object NIL : List&lt;Nothing&gt; {
      override val empty: Boolean = true
      override val head: Nothing
          get() = throw IllegalStateException("head called on empty list")
  
      override val tail: List&lt;Nothing&gt;
          get() = throw IllegalStateException("tail called on empty list")
  }
  
  private class Cons&lt;A&gt;(override val head: A,
                        override val tail: List&lt;A&gt;) : List&lt;A&gt; {
      override val empty: Boolean = false
  }
  
  fun &lt;A&gt; list(): List&lt;A&gt; = NIL // Type mismatch. Required: List&lt;A&gt;. Found: NIL
  
  fun &lt;A&gt; list(vararg a: A): List&lt;A&gt; {
      var n = list&lt;A&gt;()
      for (e in a.reversed()) {
          n = Cons(e, n)
      }
      return n
  }
  </code></pre>
  
  <p>In the standard library, this error doesn't occur, as you can see in <a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/collections/Collections.kt#L33" rel="nofollow noreferrer">EmptyList in Collections.kt</a>. Am I doing something wrong or am I missing some concepts that make the latter possible and the former not?</p>
  
  <h2>Evaluating Proposed Solutions</h2>
  
  <p>Of the three solutions proposed, the only one that allows passing the test code below is the one using the <strong>anonymous object</strong>, while the others throw the exception <code>java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Void</code>.</p>
  
  <pre><code>assertEquals("a", list&lt;String&gt;().cons("a").head)
  </code></pre>
  
  <p>However, if I change <code>NIL</code> to <code>NIL : List&lt;Any?&gt;</code>, the solution <code>NIL as List&lt;A&gt;</code> works without any problem.</p>