Reputation: 337
scala> object Test {
def unapply[L,R](v: (L, R)) = Some(v)
}
defined object Test
scala> (1, 2) match {
case 1 Test 2 => println("First")
case Test((1, 2)) => println("Second")
case _ => println("Third")
}
First
Could somebody explain why is the first case working with the object in between the two values of the tuple?
Upvotes: 5
Views: 108
Reputation: 34423
Infix operation patterns - see The Neophyte's Guide to Scala Part 1: Extractors:
If you followed the Scala course at Coursera, you learned that you can destructure lists and streams in a way that is akin to one of the ways you can create them, using the cons operator,
::
or#::
, respectively:val xs = 58 #:: 43 #:: 93 #:: Stream.empty xs match { case first #:: second #:: _ => first - second case _ => -1 }
Maybe you have wondered why that is possible. The answer is that as an alternative to the extractor pattern notation we have seen so far, Scala also allows extractors to be used in an infix notation. So, instead of writing
e(p1, p2)
, wheree
is the extractor andp1
andp2
are the parameters to be extracted from a given data structure, it’s always possible to writep1 e p2
... our
PremiumUser
extractor could also be used in a pattern that readsname PremiumUser score
. However, this is not something you would do in practice. Usage of infix operation patterns is only recommended for extractors that indeed are supposed to read like operators, which is true for the cons operators ofList
andStream
, but certainly not for ourPremiumUser
extractor.
Upvotes: 2
Reputation: 24812
From the Scala Specifications 8.1.10:
Infix Operation Patterns
An infix operation patternp;op;q
is a shorthand for the constructor or extractor patternop(p,q)
.
So
case 1 Test 2 => println("First")
is rewritten to
case Test(1, 2) => println("First")
You can actually see this in the REPL by adding //print
at the end of the line and pressing <tab>
twice:
scala> (1, 2) match { case 1 Test 2 => println("First") } //print
scala.Tuple2.apply[Int, Int](1, 2) match {
case $line10.$read.$iw.$iw.Test(1, 2) => scala.Predef.println("First")
} // : Unit
Upvotes: 5