Скала инфиксная нотация

12

Можно ли вызвать метод с использованием инфиксной записи?

Например, в Haskell я мог бы написать следующую функцию:

x `isAFactorOf` y = x % y == 0

и затем используйте это как:

if 2 `isAFactorOf` 10 ...

Что в некоторых случаях допускает очень читаемый код. Возможно ли что-нибудь подобное в Scala? Я искал "нотацию Scala Infix", но этот термин, кажется, означает что-то другое в Scala.

Carcigenicate
источник

Ответы:

15

Начиная с версии 2.10, Scala представила неявные классы для решения именно этой проблемы.

Это выполнит неявное преобразование данного типа в упакованный класс, который может содержать ваши собственные методы и значения.

В вашем конкретном случае вы бы использовали что-то вроде этого:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

Обратите внимание, что при компиляции это приведет к тому, что наше необработанное значение будет упаковано в RichInt(2). Вы можете обойти это, объявив свой RichInt как подкласс AnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

Это не вызовет бокс, но это более ограничительный, чем типичный неявный класс. Он может содержать только методы, но не значения или состояние.

KChaloux
источник
2
Вы, вероятно, должны упомянуть, что неявные классы не могут быть верхнего уровня, поэтому неявный класс должен быть определен локально.
Carcigenicate
3

По сути, в Scala вы не можете вызывать функцию инфиксным образом, но вы можете определить метод для типа, в который левый аргумент может быть неявно преобразован. Итак, для вашего примера вы можете определить класс, который имеет метод isAFactorOf (принимает Int) и указать, что Int может быть неявно преобразован в экземпляр этого класса.

Если вы посмотрите на этот ответ /programming//a/3119671 на другой вопрос, вы увидите синтаксис в Scala, который работает аналогично.

eques
источник
Стоит отметить, что новые версии Scala имеют конструкцию , явно для этого, что ответ связан не адрес: implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux