Mix infix operator with different associativity by using precedence


I would like to know if it is possible to avoid the use of parenthesis when using mixed associativity infix operators.
I have:

class Data[T]

trait PipeY[A,B] {
self =>

def run: A => B

def flatMap[C](f: PipeY[B,C]): PipeY[A, C] = new PipeY[A,C] {
  def run = (s: A) => {
    val r1 = self.run(s)

def *>[C](p: PipeY[B,C]) : PipeY[A,C] = flatMap( p )

def #:(a:A) = run(a)


class Sel1[A,B] extends PipeY[A,B] {
def run: A => B = ???
class PreProc1[A,B] extends PipeY[A,B] {
def run: A => B = ???

And I can use this so:

trait T1
trait T2
trait T3

val d1 = new Data[T1]
val d2 = new Data[T2]
val d3 = new Data[T3]

val sl1 = new Sel1[Data[T1],Data[T1]]
val sl2 = new Sel1[Data[T1],Data[T2]]
val pr1 = new PreProc1[Data[T2],Data[T2]]
val pr2 = new PreProc1[Data[T2],Data[T3]]

This works:

val c3 = d1 #: (sl1 |> sl2 |> pr1 |> pr2)

But not this:

val c3 = d1 #: sl1 *> sl2 *> pr1 *> pr2

I assumed that the higher precedence of “*” would allow the compiler to avoid the use of the parenthesis. Is this possible and if so how?


*> doesn’t have higher precedence than #:.

Precedence of infix operators is documented here in the spec as follows:

The precedence of an infix operator is determined by the operator’s first character. Characters are listed below in increasing order of precedence, with characters on the same line having the same precedence.

(all letters)
= !
< >
+ -
* / %
(all other special characters)

There’s one exception to this rule, which concerns assignment operators. The precedence of an assignment operator is the same as the one of simple assignment (=). That is, it is lower than the precedence of any other operator.

As you can see # is not listed. In other words, it belongs to (all other special characters) which have the highest precedence. If you pick an operator with lower precedence (for instance |:) it does work as you intended:

scala> val c3 = d1 |: sl1 *> sl2 *> pr1 *> pr2
scala.NotImplementedError: an implementation is missing

Thanks Jasper-M.

Unbelievable! I stared at that precedence list for so long and it didn’t occur to me that “#” is a special, not a standard character. 8-[

Thanks again.

Maybe the terminology in the spec can be improved. Though I guess you can agree that # is no letter; so by elimination that implies that it has to be a “special character” :stuck_out_tongue: