Reputation: 12104
I have a Map
that has the possibility of having a nested map of the same type. Each of those nested maps have a reference back to the outer map.
I've defined a findValue
method that looks through the current map, if it doesn't find anything, it goes to its parent, and so on until reaching null
which is the parent of the outermost SymbolTable
.
I've put this behaviour into a Try
, so that I can match on Success
and Failure
; however in order to avoid having a type a-la Try[Try[Try[ ... Try[TableVaue]... ]]]
I flatten the output.
In trying to call flatten
I get the following error: Cannot prove that Object <:< Try[U]
Here are the relevant bits of code:
class SymbolTable(val parentScope: SymbolTable) {
type TableValue = (TypeInfo, Option[Expression], Option[SymbolTable])
private val contents: mutable.Map[String, TableValue] = mutable.Map.empty
private def findValue(key: String): Try[TableValue] = Try {
if (contents contains key) contents(key)
else parentScope findValue key
}.flatten
}
So my question is: How do I make this work without any major refactoring of my code?
Upvotes: 2
Views: 610
Reputation: 67280
if (contents contains key) contents(key)
else parentScope findValue key
The type of this expression is the LUB of TableValue
(the result of contents.apply
) and Try[TableValue]
(the result of findValue
), and that is AnyRef
(or java.lang.Object
).
The following would probably work:
if (contents contains key) Try(contents(key))
else parentScope findValue key
but the whole expression is not good. Try
is only useful if you cannot avoid having to catch exceptions which is not the case here. You can perfectly use Map#get
to retrieve an Option
. With Option
it becomes much simpler:
def findValue(key: String): Option[TableValue] =
contents.get(key).orElse(parentScope.findValue(key))
If parentScope
can be null
you must guard against that too, returning None
directly.
Upvotes: 5