Ответ 1
Первый пример, T m 0, является примером "обозначения оператора". Scala имеет три типа операторских обозначений, префикс (называемый унарный), инфикс и постфикс. Здесь можно увидеть примеры всех трех:
class MyByte(val n : Int) {
require(n >= 0 && n <= 255)
def unary_! = new MyByte(n ^ 0xff)
def +(m : MyByte) = new MyByte(n + m.n)
def bits = (math.log(n) / math.log(2) + 1).toInt
override def toString = "0" * (8 - bits) + n.toBinaryString
}
Здесь он используется:
scala> val a = new MyByte(5)
a: MyByte = 00000101
scala> val b = new MyByte(10)
b: MyByte = 00001010
scala> ! a // Prefix/Unary
res58: MyByte = 11111010
scala> a + b // Infix
res59: MyByte = 00001111
scala> b bits // Postfix
res60: Int = 4
В то время как нотификаторы infix и postfix принимают любой действительный идентификатор Scala, хотя есть разговоры об ограничении нотации постфикса, в качестве префикса можно использовать только четыре идентификатора: ~,!, - и +.
Теперь, когда вы пытаетесь "m 0", Scala отбрасывает его как унарный оператор, поскольку он не является допустимым (~,!, - и +). Он обнаруживает, что "m" является допустимым объектом - это функция, а не метод, а все функции - объекты.
Поскольку "0" не является допустимым идентификатором Scala, он не может быть ни инфиксным, ни постфиксным оператором. Поэтому Scala жалуется, что он ожидал ";" - который разделил бы два (почти) действительных выражения: "m" и "0". Если вы вставляете его, то он будет жаловаться, что m требует либо аргумента, либо, в противном случае, "_", чтобы превратить его в частично примененную функцию.