Electric Coffee
Electric Coffee

Reputation: 12104

"Cannot prove that Object <:< Try[U]" in flattened function

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

Answers (1)

0__
0__

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

Related Questions