не буквенно-цифровое имя оператора приводит к ошибкам компиляции

#scala

#scala

Вопрос:

пока используются буквенно-цифровые именованные операторы piper и tapper , все в порядке. (примечание: скопировано из канала и отвода из Scala 2.13)

 package playground

object NonAlphaOperatorName {

  implicit final class MyChainingOps[A](private val me: A) extends AnyVal {
    def piper[B](f: A => B): B = f(me)
    def tapper[B](f: A => B): A = {
      f(me)
      me
    }
  }

  def main(args: Array[String]): Unit = {
    100 piper
      (r => r   1) piper
      (r => r   5) tapper
      (r => println(s"...$r...")) piper
      println
  }
}
 

Проблема: при переименовании piper |> я получаю ошибку компилятора «отсутствует тип параметра».

(Примечание: piper с другой стороны, переименование в __ (двойное подчеркивание) было бы неплохо)

 package playground

object NonAlphaOperatorName {

  implicit final class MyChainingOps[A](private val me: A) extends AnyVal {
    def |>[B](f: A => B): B = f(me)
    def tapper[B](f: A => B): A = {
      f(me)
      me
    }
  }

  def main(args: Array[String]): Unit = {
    100 |>
      (r => r   1) |>
      (r => r   5) tapper
      (r => println(s"...$r...")) |>    //error: missing parameter type [17:8]
      println
  }
}
 

Можете ли вы помочь мне объяснить эту проблему и есть ли решение этой проблемы в Scala 2.13?

Комментарии:

1. scala-lang.org/files/archive/spec/2.11/…

Ответ №1:

В ваших двух примерах у вас разный приоритет оператора.

В первом примере оба piper и tapper имеют одинаковый приоритет, поэтому код эквивалентен следующей полностью заключенной в скобки и «пунктирной» версии:

 100.piper(r => r   1).piper(r => r   5).tapper(r => println(s"...$r...")).piper(println)
 

Во втором примере |> имеет более высокий приоритет, чем tapper , поэтому код эквивалентен следующей полностью заключенной в скобки и «пунктирной» версии:

  100.|>(r => r   1).|>(r => r   5).tapper((r => println(s"...$r...")).|>(println))