我有一个界面,
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
}
它是通用的,因为我们需要H
来定义“同一类型的Heap
”,因为def merge(b: H): H
通常是根据合并相同内部结构的堆来定义的。< / p>
这对于“正常”堆很合理,即自己管理内部结构的堆:
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.
甚至一些堆积在其他堆之上:
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 + o.s, h.merge(o.h))
override def findMin: E = h.findMin
override def deleteMin = new SizedHeap[E, H](s - 1, h.deleteMin)
}
问题出现时,我们需要将它编织到我们的表示中,而不是仅仅包装原始堆:
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
override def insert(x: E) = create(merge(H(x, baseHeap.empty), h))
override def merge(o: This) = create(merge(h, o.h))
private def merge(a: BSHeap[E, BaseHeap], b: BSHeap[E, BaseHeap]): BSHeap[E, BaseHeap] = (a, b) match {
case (Empty, _) => b
case (_, Empty) => a
case (h1@H(x, p1), h2@H(y, p2)) =>
if (ord.lteq(x, y)) H(x, p1.insert(h2))
else H(y, p2.insert(h1))
}
// etc
现在的问题是,有没有比这种可爱类型注释更好的方法?
[E,
BaseHeap[X] <: Heap[X, BaseHeap[X]],
This <: BootstrappedHeap[E, BaseHeap, This]]
X
似乎没必要,虽然我找不到摆脱它的方法; This
的引用似乎有点过分; BaseHeap
在公共界面中实际上无关:我希望它是一个实现细节,我可以隐藏它吗?