I want to narrow a type when I'm pattern matching in order to special case it, but when trying to bind the tuple I'm pattern matching against to a variable, the Scala compiler seems to lose the type narrowing performed in the match. This prevents me from just forwarding the match and instead I have to recreate the tuple so that the types are preserved.
Minified example:
sealed trait Fruit
case class Apple(weight: Int = 200) extends Fruit
case object Orange extends Fruit
object PatternBinding extends App {
def handleApple(appleWithIndex: (Apple, Int)) =
println(s"Apple with weight: ${appleWithIndex._1}")
def handleFruit(fruitWithIndex: (Fruit, Int)) =
println("Other fruit")
val seq = Seq[Fruit](Apple(120), Orange, Orange, Apple())
seq.zipWithIndex.foreach {
case tup @ (apple: Apple, index) =>
handleApple(tup) // <------------ does not compile
// handleApple((apple, index)) // compiles
case tup @ (fruit, index) => handleFruit(tup)
}
}
Is there some reason for this or just a peculiar corner case?
Is there an existing issue which I may track? I tried searching, but came up empty handed.
The compiler error message:
type mismatch; found : (Fruit, Int) required: (Apple, Int)
In essence I would have expected the Apple
case to be transformed in to something like this pseudo-scala:
case tup : (Apple, Int) @ (apple: Apple, index) =>
With tup
having the type (Apple, Int)
.
Scala fiddle example: http://scalafiddle.net/console/f182c4c2e7b4bd91debd2d0d636becac
Scala version is 2.11.6.