Scala types and inheritance

I have an interface,

trait Heap[E, H <: Heap[E, H]] { implicit def ord: Ordering[E] def empty: H def isEmpty: Boolean def insert(x: E): H def merge(b: H): H def findMin: E def deleteMin: H def toList: List[E] = if (isEmpty) Nil else findMin :: deleteMin.toList } 

This is common, since we need H define โ€œa Heap the same typeโ€ because def merge(b: H): H usually defined in terms of merging a heap of the same internal structure.

This works well for "normal" heaps, i.e. heaps that themselves manage their internal structures:

 class LazyPairingHeap[E](val h: Repr[E] = Empty) (implicit val ord: Ordering[E]) extends Heap[E, LazyPairingHeap[E]] { import okasaki.heaps.LazyPairingHeap._ override def empty = new LazyPairingHeap[E](Empty) override def isEmpty: Boolean = h == Empty // etc. 

and even for some heaps built on top of other heaps:

 class SizedHeap[E, H <: Heap[E, H]](val s: Int, val h: H) extends Heap[E, SizedHeap[E, H]] { override implicit def ord: Ordering[E] = h.ord override def empty = new SizedHeap[E, H](0, h.empty) override def isEmpty = s == 0 override def insert(e: E) = new SizedHeap[E, H](s + 1, h.insert(e)) override def merge(o: SizedHeap[E, H]) = new SizedHeap[E, H](s + os, h.merge(oh)) override def findMin: E = h.findMin override def deleteMin = new SizedHeap[E, H](s - 1, h.deleteMin) } 

The problem arises when instead of simply packing the original heap, we need to weave it into our representation:

 object BootstrappedHeap { sealed trait BSHeap[+A, +H[_]] object Empty extends BSHeap[Nothing, Nothing] { override def toString = "Empty" } case class H[A, BH[_]](x: A, bsh: BH[BSHeap[A, BH]]) extends BSHeap[A, BH] { override def toString = s"H($x, $bsh)" } } abstract class BootstrappedHeap[E, BaseHeap[X] <: Heap[X, BaseHeap[X]], This <: BootstrappedHeap[E, BaseHeap, This]] (val h: BSHeap[E, BaseHeap] = Empty) (implicit ord: Ordering[E]) extends Heap[E, This] { implicit val hord: Ordering[BSHeap[E, BaseHeap]] = Ordering.by { case Empty => None case H(x, _) => Some(x) } def baseHeap: BaseHeap[BSHeap[E, BaseHeap]] def create(h: BSHeap[E, BaseHeap]): This override def empty = create(Empty) override def isEmpty: Boolean = h == Empty // etc 

Now the question is, is there a better way than this great type annotation?

 [E, BaseHeap[X] <: Heap[X, BaseHeap[X]], This <: BootstrappedHeap[E, BaseHeap, This]] 
  • X seems unnecessary, although I have not found a way to get rid of it;
  • This link seems a bit off the beat;
  • finally, BaseHeap has nothing to do with the public interface: I want this to be an implementation detail, can I hide it?
+5
source share

Source: https://habr.com/ru/post/1245680/


All Articles