After pasting Listing 19.4 (trait Queue):
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait Queue[T] {
def head: T
def tail: Queue[T]
def enqueue(x: T): Queue[T]
}
object Queue {
def apply[T](xs: T*): Queue[T] =
new QueueImpl[T](xs.toList, Nil)
private class QueueImpl[T](
private val leading: List[T],
private val trailing: List[T]
) extends Queue[T] {
def mirror =
if (leading.isEmpty)
new QueueImpl(trailing.reverse, Nil)
else
this
def head: T = mirror.leading.head
def tail: QueueImpl[T] = {
val q = mirror
new QueueImpl(q.leading.tail, q.trailing)
}
def enqueue(x: T) =
new QueueImpl(leading, x :: trailing)
}
}
// Exiting paste mode, now interpreting.
defined trait Queue
defined object Queue
I then typed out the StrangeIntQueue example:
scala> class StrangeIntQueue extends Queue[Int] {
| override def enqueue(x: Int) = {
| println(math.sqrt(x))
| super.enqueue(x)
| }
| }
<console>:16: error: method enqueue in trait Queue is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'
super.enqueue(x)
^
scala> :paste
// Entering paste mode (ctrl-D to finish)
class StrangeIntQueue extends Queue[Int] {
override def enqueue(x: Int) = {
println(math.sqrt(x))
super.enqueue(x)
}
}
// Exiting paste mode, now interpreting.
<console>:16: error: method enqueue in trait Queue is accessed from super.
It may not be abstract unless it is overridden by a member declared `abstract' and `override'
super.enqueue(x)
^
But I saw the above compile-time error. If I understand correctly, super.enqueue cannot be called from
StrangeIntQueue since its parent, i.e. Queue, is abstract.
Please let me know how to fix this compile-time error per your book's example.
Actually that is intended to not compile, but for a different reason. It was a thought-experiment to show that mutation isn't required for a covariant type to get you into soundness problems, just the type parameter appearing as the type of a value parameter in a method. The way to get the compiler error we were getting at would be to use an earlier version of Queue that was concrete. The Queue class shown before the refactor to trait Queue would probably do the trick.