Type safe Scala — Tagged types

Jun 19, 2017 · 2 min read

Today let’s talk about briefly about tagged types. A tagged type is useful when the type you’re working with is completely valid for your domain of application but still you want to add extra information to the type just as we did with phantom type parameters.

For example, let’s take the situation where we have to send information to some service, but the information needs to be protected with an ephemeral key. java.security.Key is perfectly valid, but we can use tagged types to encode the fact that the key is ephemeral, and use that information whenever we need to check we are indeed using an ephemeral key:

import java.security.Key
import javax.crypto.KeyGenerator
import tag.Taggedsealed trait Ephemeral // phantom type used to tagdef generateKey: Tagged[Key, Ephemeral] = {
val gen = KeyGenerator.getInstance("AES")
gen.init(128) // Block size

The implementation for tagging types is really simple:

object tag {  sealed trait Tag[U]
type Tagged[T, U] = T with Tag[U]
def apply[T, U](value: T): Tagged[T, U] =
value.asInstanceOf[Tagged[T, U]]

And the magic resides in that Tagged[T, U] is a subtype of T : implicitly[Tagged[T, U] <:< T] will yield a value for any T and U. Whenever we need T, we can just use the tagged type variant, but if instead we need Tagged[T, U], we cannot pass T without the required tag.

Take a look at how tagged types are implemented in shapeless, there they use @@ instead of Tagged and a class Tagger to benefit from type inference when tagging: tag[Ephemeral](key) instead of tag[Key, Ephemeral](key) as it would be in our example if we couldn’t use the inference of the return type of our generateKey function.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade