I find that after chaining Option using orElse, the element type changed, which made me impossible to use it as expected.
For example:an xml with the type of NodeSeq.
scala> xml1.headOption map { head => None } orElse xml2.lastOption map {last => Some(last)}
res11: Option[Some[ScalaObject with Equals]] = Some(Some(None))
before the orElse, head is of type Node, which is correct, but last should also be of type Node, but the compiler thinks it is of type ScalaObject with Equals, and i cannot pass last to functions take a Node as a parameter.
I can cast it using last.asInstanceOf[Node], is there a way to avoid this cast and still make last of type Node?
Try this instead (notice the added parenthesis):
The problem is that the
mapis being applied afterorElserather than beforeorElse. In other words, the expression is parsed like this:Since the expression on the left-hand-side of
orElsehas typeOption[Option[Node]]but the right-hand-side expression has typeOption[Node]the lowest common supertype isOption[ScalaObject with Equals].Scala’s flexible syntax can make coding very nice at times, but other times it results in crazy things like this. For complex expressions like this it’s a good idea to add parenthesis to make your meaning more explicit.