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?
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))
In addition to gourlaysama's answer which explains why your definition is shadowed by the built-in List
, I'd like to drop a few hints.
Empty
or CNil
case object for the 'empty' list. List
, similar to one below: sealed abstract class ConsList[+A] {
(...)
def :++:[B >: A](x : B) : ConsList[B] = new :++:(x, this)
}
It allows you to create the list using infix notation:
val b = 2 :++: 4 :++: 7 :++: CNil
And finally, you can create a companion object for easier list creation:
object ConsList {
def apply[A](xs : A*) = {
xs.foldRight(CNil : ConsList[A])((el, l) => el :++: l)
}
}
Which means that you can now create val c = ConsList(2, 4, 7)
which will be equivalent to b
above, and also equivalent to :++:(2, :++:(4, :++:(7, CNil)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.