Search code examples
scalavariadic-functionspriority-queue

PriorityQueue varargs error when extending Ordering to accomodate class objects


My goal is to create a function that takes varargs of 2 or more objects when initializing a PriorityQueue containing said objects.

The relevant code is:

case class Topic(topic: String, usageFrequency: Long = 1)  

object FreqOrdering extends Ordering[Topic] {
  def compare(a: Topic, b:Topic) = -(a.usageFrequency compare b.usageFrequency)}  

def initPriQu(a : Topic, b: Topic, c: Topic*): PriorityQueue[Topic] = {
return PriorityQueue(a,b,c)(FreqOrdering)}

Error in sbt (Scala 2):

[error] found : TopicTrenderInit.FreqOrdering.type
[error] required: scala.math.Ordering[Equals]
[error] Note: TopicTrenderInit.Topic <: Equals (and TopicTrenderInit.FreqOrdering.type <: scala.math.Ordering[TopicTrenderInit.Topic]), but trait Ordering is invariant in type T.
[error] You may wish to investigate a wildcard type such as _ <: Equals. (SLS 3.2.10)
[error] return PriorityQueue(a,b,c)(FreqOrdering)
[error] ^
[error] /home/aaron-laptop/Documents/Scala/topic_trender100/src/main/scala/main.scala:48:25: type mismatch;
[error] found : scala.collection.mutable.PriorityQueue[Equals]
[error] required: scala.collection.mutable.PriorityQueue[TopicTrenderInit.Topic]
[error] Note: Equals >: TopicTrenderInit.Topic, but class PriorityQueue is invariant in type A.
[error] You may wish to investigate a wildcard type such as _ >: TopicTrenderInit.Topic. (SLS 3.2.10)
[error] return PriorityQueue(a,b,c)(FreqOrdering)

When there is no '*' indicating a vararg everything works, no errors. I think what confuses me the worst is the required: scala.math.Ordering[Equals] error I'm seeing. I also read an article on pattern matching, but I feel i'll have to read more on it to understand implementation. What's going on here?
Thanks.


Solution

  • The problem is the way you are building the PriorityQueue. You are passing it two values of type Topic and one of type Seq[Topic] so the result is PriorityQueue[Any].

    This should work:

    def initPriQu(a : Topic, b: Topic, c: Topic*): mutable.PriorityQueue[Topic] =
      mutable.PriorityQueue(Seq(a, b) ++ c:_*)(FreqOrdering)
    

    Also, don't use return.