Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala generic: type mismatch

In the purpose of learning, I would like to understand how "::" class is working.
So I decided to create my own but instead of calling it "::" I want to call it ":++:"

From List.scala source code, the University of Helsinki and Programming In Scala 2nd edition (Chapter 22) I should write:

abstract class List[+A] {
    def isEmpty: Boolean
    def head: A
    def tail: List[A]
}

final case class :++:[A](head: A, tail: List[A]) extends List[A] {
  override def isEmpty: Boolean = false
}


I can create "::" objects

new ::(1, List(2))

But I can't create my ":++:" objects:

new :++:(1, List(2))
<console>:12: error: type mismatch;
found   : List[Int]
required: List[?]
            new :++:(1, List(2))

Where is my mistake?

like image 610
Martin Magakian Avatar asked Jan 28 '26 23:01

Martin Magakian


1 Answers

Annotating the :++: type parameter gives you a hint:

scala> new :++:[Int](1, List(2))
<console>:11: error: type mismatch;
 found   : scala.collection.immutable.scala.collection.immutable.List[Int]
 required: List(in object $iw)[Int]
              new :++:[Int](1, List(2))
                                   ^

The :++: constructor expects one of your custom List[A] instances, but you give it a normal Scala List(1).

But you currently have no way to create an instance of your list (other than having a null tail). If you add an equivalent of Nil, then you are all good:

case object Empty extends List[Nothing] { 
  def head = ???
  def isEmpty = true
  def tail = ???
}

And then you can create a :++::

scala> val a = new :++:[Int](1, Empty)
a: :++:[Int] = :++:(1,Empty)

scala> val b = new :++:(2, a)
b: :++:[Int] = :++:(2,:++:(1,Empty))
like image 68
gourlaysama Avatar answered Jan 30 '26 11:01

gourlaysama



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!