具有较高类型的不可变协变优先级队列

时间:2015-07-13 18:46:54

标签: scala covariance higher-kinded-types

我想定义不可变协变优先级队列的不同实现。首先,我希望所有实现都提供以下接口:

trait PQLike[T, This[_]] {
  def isEmpty : Boolean
  def enqueue[E >: T](x : E)(implicit ord : Ordering[E]) : This[E]
  def dequeue[T] : This[T]
  def first : T
}

以便This代表实现的类型构造函数,T是存储在队列中的元素类型。例如,如果LinearPriorityQueue[T]是优先级队列的实现,那么我希望enqueue的方法LinearPriorityQueue返回LinearPriorityQueue

我还想定义一个PriorityQueue[T]特征(或抽象类),以便优先级队列的所有实现也可以作为PriorityQueue来键入(除了它们的特定类型)。< / p>

我试过这样的事情:

trait PriorityQueue[+T] extends PQLike[T, _ <: PQLike[_,_]]

trait LinearPriorityQueue[+T] extends PriorityQueue[T] with PQLike[T,LinearPriorityQueue]    

object EPQ extends LinearPriorityQueue[Nothing] {
  def isEmpty = true
  def first = throw new PriorityQueueException("first on empty queue")
  def dequeue = throw new PriorityQueueException("dequeue on empty queue")
  def enqueue[T](x : T) = NPQ(x,this)
}

case class NPQ[+T](x : T, q : LinearPriorityQueue[T]) extends LinearPriorityQueue[T] {
  def isEmpty = false
  def first = x
  def dequeue = q
  def enqueue[E >: T](y : E) = NPQ(y,this) // not real implementation
}

但是我遇到的类型错误与我无法修复的类型相关。

由于

编辑:好的,我已经取得了一些进展。这目前正在编译并按预期工作,虽然我不知道我的解决方案是否可以进一步简化(请注意我已经做了一些重命名):

trait IsPriorityQueue[+T, +Repr[+X] <: IsPriorityQueue[X,Repr]] {
  def isEmpty : Boolean
  def first : T
  def enqueue[E >: T](x : E)(implicit ord : Ordering[E]) : Repr[E]
  def dequeue : Repr[T]
}

trait PriorityQueue[+T] extends IsPriorityQueue[T, PriorityQueue]

trait LinearPriorityQueue[+T] extends PriorityQueue[T] with IsPriorityQueue[T,LinearPriorityQueue]

object EmptyLPQ extends LinearPriorityQueue[Nothing] {
  def isEmpty = true
  def first = throw new PriorityQueueException("first on empty queue")
  def dequeue = throw new PriorityQueueException("dequeue on empty queue")
  def enqueue[E](x : E)(implicit ord : Ordering[E]) = NodeLPQ(x,this)
}

case class NodeLPQ[+T](hd : T, tl : LinearPriorityQueue[T]) extends LinearPriorityQueue[T] {
  def isEmpty = false
  def first = hd
  def dequeue = tl
  def enqueue[E >: T](x : E)(implicit ord : Ordering[E]) =
    if(ord.compare(x,hd)<0)
      NodeLPQ(x,this)
    else
      NodeLPQ(hd,tl.enqueue(x))
}

我想对我的代码和可能的简化进行评论。我也在想也许可以使用存在类型来定义特质PriorityQueuePriorityQueue扩展某些表示IsPriorityQueue的东西但是还没有能够表达出来。

编辑:是否有人对我的解决方案有任何意见?

0 个答案:

没有答案