I’m wrapping mutable.buffer to provide a Deque, using the normal implicit conversion mechanism. However if I use implicit class Deque
in the code below it doesn’t work and I have to use a separate “old style” implicit def BufferToDeque
as shown below to to the wrapping, otherwise I get the following comilation error:
Error:(33, 71) value unprepend is not a member of scala.collection.mutable.ListBuffer[Int] def get$$instance$$res2 = /* ###worksheet### generated $$end$$ */ ab.unprepend()
Why?
import scala.collection.{mutable => m} object Deque { import scala.language.higherKinds class Deque[E, B[E] <: m.Buffer[E]](buf: B[E]) extends m.ArrayBuffer[E] { def unprepend(): E = return buf.remove(0) // Additional methods elided } implicit def BufferToDeque[E, B[E] <: m.Buffer[E]](b: B[E]): Deque.Deque[E, B] = return new Deque(b) } import scala.language.implicitConversions import Deque._ val b = m.ListBuffer(2,3,4) b.prepend(0,1) b b.unprepend() b
The code above works for both ListBuffer
and ArrayBuffer
and does returns ListBuffer
when called on a ListBuffer
, even though it extends ArrayBuffer
- you have to use ArrayBuffer
, you can’t extend Buffer
as it’s abstract and you can’t extend ListBuffer
as it’s final (why?).
b: scala.collection.mutable.ListBuffer[Int] = ListBuffer(2, 3, 4) res0: Unit = () res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(0, 1, 2, 3, 4) res2: Int = 0 res3: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
This works but it’s kinda … unsatisfactory
Also, I have a feeling I may be missing a covariance annotation but I’m not sure where it would go…