I'm using a priority queue to order a case class called TreeNodeWithCostAndHeuristic
case class TreeNodeWithCostAndHeuristic[S,A](parent:Option[TreeNodeWithCostAndHeuristic[S,A]],
action: Option[A],
state: S,
cost: Double,
estimatedRemainingCost: Double)
This priority queue is created inside a function that uses its parameter to set the initial state while the other values have to be kept as None or 0
def HeuristicGraphSearch[S,A](problem: ProblemWithCostAndHeuristic[S,A]) = {
val root = TreeNodeWithCostAndHeuristic(parent = None,action=None,state=problem.initialState,cost = 0.0, estimatedRemainingCost = 0.0)
val frontier : mutable.PriorityQueue[TreeNodeWithCostAndHeuristic[S,A]] = mutable.PriorityQueue.empty[TreeNodeWithCostAndHeuristic[S,A]]
frontier.enqueue(root)
However because parent and action are none I get a mismatch between expected type TreeNodeWithCostAndHeuristic[S,A]
and the one I'm trying to enqueue TreeNodeWithCostAndHeuristic[S,Nothing]
.
As far as I know Nothing is a subtype of Option and in my case class both parent and action are options. Why am I getting the mismatch?
It's related to the way Scala compiler infers types. Short answer is to simply help it out a bit by explicitly declaring the types when constructing your case class:
val root = TreeNodeWithCostAndHeuristic[S, A](parent = None,action=None,state=problem.initialState,cost = 0.0, estimatedRemainingCost = 0.0)
Reason why TreeNodeWithCostAndHeuristic[S, Nothing]
is not considered a valid substitute for TreeNodeWithCostAndHeuristic[S, A]
is because it's not its subclass; to be one, it would have to be covariant in type A. If some Foo[A]
is covariant in its type A
, only then the following holds: Foo[S] <: Foo[A]
for any S
that is subclass of A
.
In addition to sloucs answer, you can also use type ascription to help the compiler out:
val root = TreeNodeWithCostAndHeuristic(
parent = None: Option[TreeNodeWithCostAndHeuristic[S, A]],
action = None: Option[A],
state = problem.initialState,
cost = 0.0,
estimatedRemainingCost = 0.0)
The reason the compiler is complaining is that it has no way to guarantee None.type
is a Option[TreeNodeWithCostAndHeuristic[S, A]]
and Option[A]
, respectively, and thus it "bails out" and infers Nothing
, which is the bottom type of all types.
@Dima also suggests using Option.empty[A]
:
val root = TreeNodeWithCostAndHeuristic(
parent = Option.empty,
action = Option.empty[A],
state = problem.initialState,
cost = 0.0,
estimatedRemainingCost = 0.0)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.