January 05, 2014

Out of the box, Scala supports infix functions via a syntactic nuance; a function with a symbolic name ending in a colon may be written to the left of the instance on which it is defined.

Consider the class `MyNum`

:

```
case class MyNum(x: Int) {
def +:(y: Int): Int = x + y
}
```

Because the addition function `+:`

ends in a colon, we can use it as both a prefix and an infix function:

```
val x = MyNum(21).+:(21) // 42
val y = 21 +: MyNum(21) // 42
```

This is handy, but somewhat syntactically limited. Fortunately, we can do better.

Consider the trait `Semigroup`

:

```
trait Semigroup[A] {
def append(a1: A, a2: A): A
}
```

Any type `A`

can have a semigroup if we can implement `append`

for it:

```
val listSemigroup =
new Semigroup[List[Int]] {
def append(a1: List[Int], a2: List[Int]): List[Int] = a1 ++ a2
}
import listSemigroup._
val list = append(List(1,2,3), List(4,5,6)) // List(1,2,3,4,5,6)
```

So far, we have a prefix-notation function `append`

that takes two lists, `a1`

and `a2`

, and concatenates them. Let's augment `Semigroup`

, adding a type class that lifts `a1`

into a new type that has its own `append`

function:

```
trait Semigroup[A] {
def append(a1: A, a2: A): A
class InfixSemigroup(a1: A) {
def ⋅(a2: A): A = Semigroup.this.append(a1, a2)
}
implicit def infix(a1: A) = new InfixSemigroup(a1)
}
```

We can use our same `listSemigroup`

implementation, which now has an implicit `infix`

function to convert `a1`

into an `InfixSemigroup`

instance, which has its own `append`

function called `⋅`

:

```
val listSemigroup =
new Semigroup[List[Int]] {
def append(a1: List[Int], a2: List[Int]): List[Int] = a1 ++ a2
}
import listSemigroup._
val list = List(1,2,3) ⋅ List(4,5,6) // List(1,2,3,4,5,6)
```