Reputation: 12092
I am trying to define a binary tree with the following definition:
trait Node {
val label: Int
}
case class BranchNode(override val label: Int, left: Option[Node], right: Option[Node]) extends Node
case class LeafNode(override val label: Int) extends Node
and then define a simple printTree
method using Scala's pattern matching as below:
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
}
The Intellij IDE warns me that the match may not be exhaustive. An Option
can have None
or Some
as it's values. In case of Option[Node]
, it can either be Some(LeafNode)
or Some(BranchNode)
. What other cases am I overlooking?
Upvotes: 2
Views: 3464
Reputation: 31262
Definitely its a compiler warning, see below I'm breaking your code, by passing printTree(Option(IWillBreakYou(2)))
trait Node {
val label: Int
}
case class BranchNode(override val label: Int, left: Option[Node], right: Option[Node]) extends Node
case class LeafNode(override val label: Int) extends Node
case class IWillBreakYou(override val label: Int) extends Node
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
}
val leftNode = Option(LeafNode(2))
val rightNode = Option(LeafNode(3))
printTree(Option(BranchNode(1, leftNode, rightNode)))
printTree(Option(IWillBreakYou(2))) //this will fail
The reason is since you are taking Option[Node]
AND anybody can extend Node
(within/outside of package unless protected) which you are not considering in your matches.
So, adding failsafe match case _
would fix the future error.
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
case _ => println("do nothing")
}
Upvotes: 3
Reputation: 149636
Since your trait isn't sealed
, it is open for extension in different packages. IntelliJ is warning you of the future possibility that anyone extending this trait and forgetting to implement an additional case
may cause a MatchError
. If you want to limit it's extension, use:
sealed trait Node
Upvotes: 6