## Unboxed new types within Scalaz7

Some time ago I started investigating the latest (and as yet unreleased) version of Scalaz. Version 7.x is markedly different to version 6.x; utilising a totally different design that makes a distinct split between core abstractions and the syntax to work with said abstractions. In any case, thats fodder for another post; the bottom line is that Scalaz7 is really, really slick - I like the look of it a lot and I feel like theres a lot to be learnt by simply studying the codebase and throwing around the abstractions therein (this may be less true for haskell gurus, but for mere mortals like myself I've certainly found it insightful).

One of the really neat things that Scalaz7 makes use of is a very clever trick with types in order to disambiguate typeclass instances for a given type `T`

. This was something Miles demonstrated some time ago in a gist, and I was intrigued to find it being used in Scalaz7.

So then, what the hell does all this mean you might be wondering? Well, consider a `Monoid`

of type `Int`

like so:

```
scala>import scalaz._, std.anyVal._
import scalaz._
import std.anyVal._
scala> Monoid[Int].append(10,20)
res1: Int = 30
```

...or with sugary syntax imported as well:

```
scala>import scalaz._, syntax.semigroup._, std.anyVal._
import scalaz._
import syntax.semigroup._
import std.anyVal._
scala> 10 |+| 20
res2: Int = 30
```

This is simple use of the `Monoid`

type, and this example uses the default type class instance for `Int`

, which simply sums two numbers together. But, consider another case for `Int`

: what if you needed to multiply those same numbers instead?

If there were two typeclass instances for `Monoid[Int]`

, unless they were in separate objects, packages or jars there would be an implicit ambiguity which would not compile: the type system would not *implciitly* be able to determine which typeclass it should apply when considering an operation on monoids of Int.

This issue has been overcome in Scalaz7 by using the type tagging trick mentioned in the introduction. Specifically, the default behaviour for `Monoid[Int]`

is addition, and then a second typeclass exists for `Monoid[Int @@ Multiplication]`

. The `@@`

syntax probably looks a little funny, so lets look at how its used and then talk in more detail about how that works:

```
scala>import Tags._
import Tags._
scala> Multiplication(2) |+| Multiplication(10)
res14: scalaz.package.@@[Int,scalaz.Tags.Multiplication] = 20
```

You'll notice that the value was multiplied this time, giving the correct result of 20, but you may well be wondering about the resulting type signature of `@@[Int,Multiplication]`

... this is where it gets interesting.

`Multiplication`

just acts as a small bit of plumbing to produce a type of `A`

, tagged with `Multiplication`

; and this gives you the ability to define a type which is distinct from another - even if they are "the same" (so to speak). The definition of `Multiplication`

is like so:

```
sealed trait Multiplication
def Multiplication[A](a: A): A @@ Multiplication = Tag[A, Multiplication](a)
object Tag {
@inline def apply[A, T](a: A): A @@ T = a.asInstanceOf[A @@ T]
...
}
```

The `Tag`

object simply tags types of `A`

with a specified marker of `T`

; or, in this case, `Multiplication`

, where the result is `A @@ T`

. I grant you, it looks weird to start with, but the definition of `@@`

is quite straight forward:

`type @@[T, Tag] = T with Tagged[Tag]`

Where `Tagged`

in turn is a structural type:

`type Tagged[T] = {type Tag = T}`

The really clever thing here is that this whole setup is just at the type-level: the values are just `Int`

in the underlying byte code. That is to say if we had something like:

```
def foobar(i: Int): Int @@ Multiplication = ...
```

When compiled it would actually end up being:

`def foobar(i: Int): Int = … `

Which is pretty awesome. This sort of strategy is obviously quite generic and there are a range of different tags within Scalaz7, including selecting first and last operands of a monoid, zipping with applicatives, conjunction and disjunctions etc. All very neat stuff!