Singleton types for literals in Scala

It’s sometimes useful in Scala to have a type with a single value. These are called singleton types, and they show up most easily in the context of Scala’s objects. For example, if we have the following definition:

We can refer to a type foo.type that is the singleton type for foo—i.e., the type that contains nothing except foo. We can use this type to write a function that won’t compile with any non-foo argument:

For example:

Note that this error message doesn’t just tell us that we provided a String when we needed a foo—it lists the type as String("foo"). This is because string literals—like all other literals in Scala (except function literals)—are also singletons in the sense that their most specific type is a singleton type.

Unfortunately Scala doesn’t provide the .type syntax for literals—we can’t write "foo".type, for example (except in a compiler fork by Paul Phillips). Macro Paradise’s type macros get pretty close by allowing us to write something like singleton("foo") to refer to this type, but the 2.11 release is half a year away, and there’s no guarantee it will include type macros, anyway. We can get what we want while we’re waiting, though, if we’re willing to pay a bit of syntax tax.

We can start with the following macro:

This isn’t paradise, but it is code you can copy and paste into your 2.10 REPL today. Next we can define a method for lifting values into LiteralSingleton:

And then:

The type alias is just a syntactic convenience—we could just as easily refer to thirteen.T directly in our method definitions, etc.

We can also write a macro that will give us the (unique) inhabitant of a singleton type:

And then:

Now we can write the following:

For a concrete example of how singleton types for literals can be used in Scala, see Alois Cochard’s Shona library and this ScalaDays 2013 presentation by Ismael Juma and Alois. Shona uses type macros instead of the approach I’ve described here, but I’ve put together a proof-of-concept port to 2.10 that only needs def macros.