PriorityQueue varargs error when extending Ordering to accomodate class objects












0















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.










share|improve this question





























    0















    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.










    share|improve this question



























      0












      0








      0








      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.










      share|improve this question
















      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.







      scala variadic-functions priority-queue






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 31 '18 at 17:06







      A.Lopez

















      asked Dec 31 '18 at 16:55









      A.LopezA.Lopez

      156




      156
























          2 Answers
          2






          active

          oldest

          votes


















          5














          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.






          share|improve this answer
























          • in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 17:18








          • 1





            @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

            – SergGr
            Dec 31 '18 at 19:05













          • @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 19:20











          • thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

            – A.Lopez
            Jan 2 at 18:40








          • 1





            @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

            – Tim
            Jan 2 at 18:58



















          1














          The problem is that, when you pass a, b, c to the Factory of PriorityQueue. What the compilers see is that you passed three arguments of type A and the only super type between those tree is Equals.

          That is because a & b are Topics, which as a case class extends Equals, and c is of type Seq[Topic] (a varargs arguments is passed as a Seq), which also extends Equals.

          And that is why it is asking for a Ordering[Equals].



          You may fix it as follows.
          (Note this is quite ugly and maybe innificient, you may consider just recieve one varargs instead of a & b and then c)



          // It will be good to have this as an implicit so you don't have to pass it explicitly
          // every time you need to.
          // And it is always preferable to have an implicit val with an explicit type signature
          // than an implicit object.
          implicit val TopicOrdering: Ordering[Topic] = new math.Ordering[Topic] {
          override def compare(a: Topic, b:Topic): Int =
          -(a.usageFrequency compare b.usageFrequency)
          }

          import scala.collection.mutable.PriorityQueue
          def initPriQu(a: Topic, b: Topic, others: Topic*): PriorityQueue[Topic] =
          // 1. Don't use return in scala.
          // 2. Here I made a Seq of Seqs of Topic - Seq[Seq[Topic]]
          // then I flatten it to have a Seq of Topic - Seq[Topic]
          // and finally used the ':_*' operator to turn a Seq into a varargs.
          PriorityQueue((Seq(a, b) ++ others): _*)





          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53989701%2fpriorityqueue-varargs-error-when-extending-ordering-to-accomodate-class-objects%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5














            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.






            share|improve this answer
























            • in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 17:18








            • 1





              @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

              – SergGr
              Dec 31 '18 at 19:05













            • @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 19:20











            • thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

              – A.Lopez
              Jan 2 at 18:40








            • 1





              @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

              – Tim
              Jan 2 at 18:58
















            5














            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.






            share|improve this answer
























            • in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 17:18








            • 1





              @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

              – SergGr
              Dec 31 '18 at 19:05













            • @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 19:20











            • thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

              – A.Lopez
              Jan 2 at 18:40








            • 1





              @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

              – Tim
              Jan 2 at 18:58














            5












            5








            5







            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.






            share|improve this answer













            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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 31 '18 at 17:14









            TimTim

            5,7681617




            5,7681617













            • in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 17:18








            • 1





              @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

              – SergGr
              Dec 31 '18 at 19:05













            • @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 19:20











            • thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

              – A.Lopez
              Jan 2 at 18:40








            • 1





              @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

              – Tim
              Jan 2 at 18:58



















            • in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 17:18








            • 1





              @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

              – SergGr
              Dec 31 '18 at 19:05













            • @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

              – Luis Miguel Mejía Suárez
              Dec 31 '18 at 19:20











            • thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

              – A.Lopez
              Jan 2 at 18:40








            • 1





              @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

              – Tim
              Jan 2 at 18:58

















            in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 17:18







            in terms of performance (and knowing that Seq will probably be a List in runtime) will it be better to concatenate both Seqs or to use flatten?

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 17:18






            1




            1





            @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

            – SergGr
            Dec 31 '18 at 19:05







            @LuisMiguelMejíaSuárez, I think for List the fastest implemetnation will be a +: b +: c:_* because it will use +: from List which will be just a wrapper over :: which is O(1). However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here ++ for List is a wrapper over ::: which will be pretty good as well without any big sacrifices for other possible types. AFAIK your flatten is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization to flatten.

            – SergGr
            Dec 31 '18 at 19:05















            @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 19:20





            @SergGr after searching a bit I found that varargs are implemented using a WrappedArray not a List, so yes Tim's solution using ++ will be the best one. I will update my answer to use it too.

            – Luis Miguel Mejía Suárez
            Dec 31 '18 at 19:20













            thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

            – A.Lopez
            Jan 2 at 18:40







            thank you, all these comments are enlightening. What is the reason to not use the return keyword? Is it for better readability or a more functional reason?

            – A.Lopez
            Jan 2 at 18:40






            1




            1





            @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

            – Tim
            Jan 2 at 18:58





            @A.Lopez The problem with return is that it is not necessary in the simple cases and can have unexpected behaviour in complex cases. In the simple case you can just use an expression as the return value. In complex cases it can jump out of multiple nested blocks and it is not always clear where it jumps to!

            – Tim
            Jan 2 at 18:58













            1














            The problem is that, when you pass a, b, c to the Factory of PriorityQueue. What the compilers see is that you passed three arguments of type A and the only super type between those tree is Equals.

            That is because a & b are Topics, which as a case class extends Equals, and c is of type Seq[Topic] (a varargs arguments is passed as a Seq), which also extends Equals.

            And that is why it is asking for a Ordering[Equals].



            You may fix it as follows.
            (Note this is quite ugly and maybe innificient, you may consider just recieve one varargs instead of a & b and then c)



            // It will be good to have this as an implicit so you don't have to pass it explicitly
            // every time you need to.
            // And it is always preferable to have an implicit val with an explicit type signature
            // than an implicit object.
            implicit val TopicOrdering: Ordering[Topic] = new math.Ordering[Topic] {
            override def compare(a: Topic, b:Topic): Int =
            -(a.usageFrequency compare b.usageFrequency)
            }

            import scala.collection.mutable.PriorityQueue
            def initPriQu(a: Topic, b: Topic, others: Topic*): PriorityQueue[Topic] =
            // 1. Don't use return in scala.
            // 2. Here I made a Seq of Seqs of Topic - Seq[Seq[Topic]]
            // then I flatten it to have a Seq of Topic - Seq[Topic]
            // and finally used the ':_*' operator to turn a Seq into a varargs.
            PriorityQueue((Seq(a, b) ++ others): _*)





            share|improve this answer






























              1














              The problem is that, when you pass a, b, c to the Factory of PriorityQueue. What the compilers see is that you passed three arguments of type A and the only super type between those tree is Equals.

              That is because a & b are Topics, which as a case class extends Equals, and c is of type Seq[Topic] (a varargs arguments is passed as a Seq), which also extends Equals.

              And that is why it is asking for a Ordering[Equals].



              You may fix it as follows.
              (Note this is quite ugly and maybe innificient, you may consider just recieve one varargs instead of a & b and then c)



              // It will be good to have this as an implicit so you don't have to pass it explicitly
              // every time you need to.
              // And it is always preferable to have an implicit val with an explicit type signature
              // than an implicit object.
              implicit val TopicOrdering: Ordering[Topic] = new math.Ordering[Topic] {
              override def compare(a: Topic, b:Topic): Int =
              -(a.usageFrequency compare b.usageFrequency)
              }

              import scala.collection.mutable.PriorityQueue
              def initPriQu(a: Topic, b: Topic, others: Topic*): PriorityQueue[Topic] =
              // 1. Don't use return in scala.
              // 2. Here I made a Seq of Seqs of Topic - Seq[Seq[Topic]]
              // then I flatten it to have a Seq of Topic - Seq[Topic]
              // and finally used the ':_*' operator to turn a Seq into a varargs.
              PriorityQueue((Seq(a, b) ++ others): _*)





              share|improve this answer




























                1












                1








                1







                The problem is that, when you pass a, b, c to the Factory of PriorityQueue. What the compilers see is that you passed three arguments of type A and the only super type between those tree is Equals.

                That is because a & b are Topics, which as a case class extends Equals, and c is of type Seq[Topic] (a varargs arguments is passed as a Seq), which also extends Equals.

                And that is why it is asking for a Ordering[Equals].



                You may fix it as follows.
                (Note this is quite ugly and maybe innificient, you may consider just recieve one varargs instead of a & b and then c)



                // It will be good to have this as an implicit so you don't have to pass it explicitly
                // every time you need to.
                // And it is always preferable to have an implicit val with an explicit type signature
                // than an implicit object.
                implicit val TopicOrdering: Ordering[Topic] = new math.Ordering[Topic] {
                override def compare(a: Topic, b:Topic): Int =
                -(a.usageFrequency compare b.usageFrequency)
                }

                import scala.collection.mutable.PriorityQueue
                def initPriQu(a: Topic, b: Topic, others: Topic*): PriorityQueue[Topic] =
                // 1. Don't use return in scala.
                // 2. Here I made a Seq of Seqs of Topic - Seq[Seq[Topic]]
                // then I flatten it to have a Seq of Topic - Seq[Topic]
                // and finally used the ':_*' operator to turn a Seq into a varargs.
                PriorityQueue((Seq(a, b) ++ others): _*)





                share|improve this answer















                The problem is that, when you pass a, b, c to the Factory of PriorityQueue. What the compilers see is that you passed three arguments of type A and the only super type between those tree is Equals.

                That is because a & b are Topics, which as a case class extends Equals, and c is of type Seq[Topic] (a varargs arguments is passed as a Seq), which also extends Equals.

                And that is why it is asking for a Ordering[Equals].



                You may fix it as follows.
                (Note this is quite ugly and maybe innificient, you may consider just recieve one varargs instead of a & b and then c)



                // It will be good to have this as an implicit so you don't have to pass it explicitly
                // every time you need to.
                // And it is always preferable to have an implicit val with an explicit type signature
                // than an implicit object.
                implicit val TopicOrdering: Ordering[Topic] = new math.Ordering[Topic] {
                override def compare(a: Topic, b:Topic): Int =
                -(a.usageFrequency compare b.usageFrequency)
                }

                import scala.collection.mutable.PriorityQueue
                def initPriQu(a: Topic, b: Topic, others: Topic*): PriorityQueue[Topic] =
                // 1. Don't use return in scala.
                // 2. Here I made a Seq of Seqs of Topic - Seq[Seq[Topic]]
                // then I flatten it to have a Seq of Topic - Seq[Topic]
                // and finally used the ':_*' operator to turn a Seq into a varargs.
                PriorityQueue((Seq(a, b) ++ others): _*)






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Dec 31 '18 at 19:21

























                answered Dec 31 '18 at 17:14









                Luis Miguel Mejía SuárezLuis Miguel Mejía Suárez

                2,5621822




                2,5621822






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53989701%2fpriorityqueue-varargs-error-when-extending-ordering-to-accomodate-class-objects%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas