Scala инфиксная нотация с объектом +, почему это невозможно?

Я могу назвать такие объекты, но не могу вызвать m:

object + {
  def m (s: String) = println(s)
}

Нельзя вызвать +.m("hi"):

<console>:1: error: illegal start of simple expression
       +.m("hi")

Также не может вызывать + m "hi" (предпочтительнее для использования DSL).

Но с object ++ он отлично работает! Вступают ли они в конфликт с (не существующими) методами unary_+? Можно ли избежать этого?

Ответ 1

Действительно, это невозможно с унарными операторами. Если вы хотите называть это в любом случае, вы можете прибегнуть к использованию имени, сгенерированного компилятором для JVM (начинающегося с доллара):

scala> object + {
     | def m( s: String ) = println(s)
     | }
defined module $plus

scala> +.m("hello")
<console>:1: error: illegal start of simple expression
       +.m("hello")
        ^

scala> $plus.m("hello")
hello

Ответ 2

Я считаю, что проблема заключается в том, что для обработки унарных операторов без двусмысленности scala опирается на частный случай: только !, +, - и ~ рассматриваются как унарные операторы. Таким образом, в +.m("hi"), scala рассматривают + как унарный оператор и не могут понять все выражение.

Ответ 3

Другой код с использованием пакета:

object Operator extends App {
    // http://stackoverflow.com/info/13367122/scalas-infix-notation-with-object-why-not-possible
    pkg1.Sample.f
    pkg2.Sample.f
}

package pkg1 {
    object + {
        def m (s: String) = println(s)
    }

    object Sample {
        def f = {
            // +.m("hi") => compile error: illegal start of simple expression
            // + m "hi" => compile error: expected but string literal found.
            $plus.m("hi pkg1")
            $plus m "hi pkg1"
        }
    }
}

package pkg2 {
    object + {
        def m (s: String) = println(s)
    }

    object Sample {
        def f = {
            pkg2.+.m("hi pkg2")
            pkg2.+ m "hi pkg2"
            pkg2.$plus.m("hi pkg2")
            pkg2.$plus m "hi pkg2"
        }
    }
}

java version "1.7.0_09"

Scala версия кода 2.9.2