Infix Prefix And Postfix Operators

Any method which takes a single parameter can be used as an infix operator: a.m(b) can also be written as a m b.

val g: Int = 3
(g + 4) should be(res0) // + is an infix operator
g.+(4) should be(res1)

Infix operators do NOT work if an object has a method that takes two parameters:

val g: String = "Check out the big brains on Brad!"

g indexOf 'o' should be(res0) //indexOf(Char) can be used as an infix operator

// g indexOf 'o', 4 should be (6) //indexOf(Char, Int) cannot be used as an infix operator

g.indexOf('o', 7) should be(res1)

Any method which does not require a parameter can be used as a postfix operator: a.m can be written as a m.

For instance, a.+(b) is equivalent to a + b and a.! is the same as a!.

Postfix operators have lower precedence than infix operators, so:

  • foo bar baz means foo.bar(baz).
  • foo bar baz bam means (foo.bar(baz)).bam
  • foo bar baz bam bim means (foo.bar(baz)).bam(bim).
val g: Int = 31
(g toHexString) should be(
  res0)

Prefix operators work if an object has a method name that starts with unary_ :

val g: Int = 31
(-g) should be(res0)

Here's how to create a prefix operator for our own class. The only identifiers that can be used as prefix operators are +, -, !, and ~:

class Stereo {
  def unary_+ = "on"

  def unary_- = "off"
}

val stereo = new Stereo
(+stereo) should be(res0)
(-stereo) should be(res1)