14

Is it possible to call a method using infix notation?

For example, in Haskell, I could write the following function:

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

and then use it like:

if 2 `isAFactorOf` 10 ...

Which in some cases allows for very readable code. Is anything similar to this possible in Scala? I searched for "Scala infix notation", but that term seems to mean something different in Scala.

2 Answers 2

17

Starting with version 2.10, Scala introduced implicit Classes to handle precisely this issue.

This will perform an implicit conversion on a given type to a wrapped class, which can contain your own methods and values.

In your specific case, you'd use something like this:

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

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

Note that when compiled, this will end up boxing our raw value into a RichInt(2). You can get around this by declaring your RichInt as a subclass of AnyVal:

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

This won't cause boxing, but it's more restrictive than a typical implicit class. It can only contain methods, not values or state.

1
  • 2
    You should probably mention that implicit classes can't be top-level, so the implicit class will need to be defined locally. Dec 20, 2014 at 15:54
3

Essentially, in Scala you can't call a function in an infix manner, but you can define a method on a type, which the left argument can be converted to implicitly. So for your example, you can define a class which has a method isAFactorOf (taking an Int) and indicate that an Int can be implicitly converted to an instance of this class.

If you look at this answer https://stackoverflow.com/a/3119671 to another question, you will see the syntax in Scala which works equivalently.

1
  • It's worth pointing out that new versions of Scala have a construct explicitly for this, which the answer linked does not address: implicit class RichInt(i: Int) { def square() = i * i }.
    – KChaloux
    Dec 5, 2014 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.