I am learning Scala, and playing with right associate unapply object. I know that if the name ends with ':' then it becomes right associative. However, there seems to be some strange restrictions on the naming
e.g.
These are invalid
object cons: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
object :_cons_: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
These are valid
object cons_: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
object >>: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
So there seems to be some weirdness about mixing alpha-numeric characters and symbols in identifiers.
So basically, I want to have a descriptive name i.e. 'cons' and still have right associativity. Also, I would like my operator to be symetric for aesthetic reasons :-), so I dont really like cons_:
Is there a way to make something associate to the right without using a colon? Or any other suggestions to achieve this?
:_cons_:
seems to be the closest, but, for some reason the identifier can't start with ':' and have alphanumerics
From the spec (section 1.1):
There are three ways to form an identifier. First, an identifier can
start with a letter which can be followed by an arbitrary sequence of
letters and digits. This may be followed by underscore ‘_’ characters
and another string composed of either letters and digits or of
operator characters. Second, an identifier can start with an operator
character followed by an arbitrary sequence of operator characters.
The preceding two forms are called plain identifiers. Finally, an
identifier may also be formed by an arbitrary string between
back-quotes (host systems may impose some restrictions on which
strings are legal for identifiers). The identifier then is composed of
all characters excluding the backquotes themselves.
So it looks like you're out of luck—if your identifier starts with a :
it can't contain non-operator characters. Note, though, that you can write the following (which isn't intended to do anything meaningful—just to demonstrate the syntax):
scala> class X { def `:cons:`(i: Int) = i }
defined class X
scala> val x = new X
x: X = X@6a665da6
scala> 1 `:cons:` x
res1: Int = 1
The method name still ends with a colon, so you get the right associativity you're looking for.