I have a case class
case class ~[a,b](_1:a, _2:b)
When I want to do pattetn matching
new ~("a", 25) match{
case "a" ~ 25 =>
}
I can use it this way because "a" ~ 25 and ~("a", 25) are equivalent. But if I want to match new ~("a", new ~("b", 25)) by {case "a" ~ "b" ~ 25 => } troubles begin. I understand that this statements aren’t equivalent. So, how new ~("a", new ~("b", 25)) can be presented? By what rules?
This works:
So, you’ll have to put the parentheses the same way they are in the initial clause. Otherwise the tilde is left-associative, therefore the type of the pattern will be different and it won’t compile.
is the same as
which would be wrong in your case.
Appendix
You can get right-associativity by having a colon as the last character in your class/method name. The following compiles and matches without parentheses (and you can drop the
newas the compiler won’t be confused anymore by$tilde$colon):Responses
1) Without the
newkeyword, thecase class ~is shadowed byunary_~which gives the bitwise negation of the argument. An expression like~ 2is internally evaluated tounary_~(2)and the same goes for the case of~ ("a", 1)– however unless you defineunary_~on that tuple, this will give an error. With thenewkeyword you advise the compiler to explicitly look for a class with that name, so it won’t get confused.(Technically, you could work around this by using
$tilde("a", 1)which is the internal name for yourcase class ~, but since this is a compiler detail, you should probably not rely on it.)2&3) The right-associativity is referenced in the Scala Language Specification. Section ‘Infix Operations’
By the way, right-associativity is the trick that allows for creating lists with
Nil. (Nilis the emptyListand has the right-associative concatenation operator::defined.)which is evaluated as follows
or, more precisely, since
3 :: Nil≡Nil.::(3), as