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.
scala variadic-functions priority-queue
add a comment |
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
add a comment |
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
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
scala variadic-functions priority-queue
edited Dec 31 '18 at 17:06
A.Lopez
asked Dec 31 '18 at 16:55
A.LopezA.Lopez
156
156
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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
.
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 forList
the fastest implemetnation will bea +: b +: c:_*
because it will use+:
fromList
which will be just a wrapper over::
which isO(1)
. However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here++
forList
is a wrapper over:::
which will be pretty good as well without any big sacrifices for other possible types. AFAIK yourflatten
is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization toflatten
.
– SergGr
Dec 31 '18 at 19:05
@SergGr after searching a bit I found that varargs are implemented using aWrappedArray
not aList
, 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 withreturn
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
add a comment |
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): _*)
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
.
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 forList
the fastest implemetnation will bea +: b +: c:_*
because it will use+:
fromList
which will be just a wrapper over::
which isO(1)
. However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here++
forList
is a wrapper over:::
which will be pretty good as well without any big sacrifices for other possible types. AFAIK yourflatten
is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization toflatten
.
– SergGr
Dec 31 '18 at 19:05
@SergGr after searching a bit I found that varargs are implemented using aWrappedArray
not aList
, 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 withreturn
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
add a comment |
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
.
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 forList
the fastest implemetnation will bea +: b +: c:_*
because it will use+:
fromList
which will be just a wrapper over::
which isO(1)
. However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here++
forList
is a wrapper over:::
which will be pretty good as well without any big sacrifices for other possible types. AFAIK yourflatten
is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization toflatten
.
– SergGr
Dec 31 '18 at 19:05
@SergGr after searching a bit I found that varargs are implemented using aWrappedArray
not aList
, 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 withreturn
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
add a comment |
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
.
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
.
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 forList
the fastest implemetnation will bea +: b +: c:_*
because it will use+:
fromList
which will be just a wrapper over::
which isO(1)
. However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here++
forList
is a wrapper over:::
which will be pretty good as well without any big sacrifices for other possible types. AFAIK yourflatten
is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization toflatten
.
– SergGr
Dec 31 '18 at 19:05
@SergGr after searching a bit I found that varargs are implemented using aWrappedArray
not aList
, 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 withreturn
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
add a comment |
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 forList
the fastest implemetnation will bea +: b +: c:_*
because it will use+:
fromList
which will be just a wrapper over::
which isO(1)
. However for other underlying collections performance might be pretty bad because 2 copies might be required. The suggested here++
forList
is a wrapper over:::
which will be pretty good as well without any big sacrifices for other possible types. AFAIK yourflatten
is not overridden in any class so there are no optimizations at all and actually it is harder to add optimization toflatten
.
– SergGr
Dec 31 '18 at 19:05
@SergGr after searching a bit I found that varargs are implemented using aWrappedArray
not aList
, 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 withreturn
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
add a comment |
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): _*)
add a comment |
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): _*)
add a comment |
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): _*)
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): _*)
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
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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