Problem
When I work with libraries that support level programming, I often find that I write comments similar to the following (from the example presented by Paul Snively at Strange Loop 2012 ):
Or this, from an example in Shapeless :
/** * If we wanted to confirm that the list uniquely contains `Foo` or any * subtype of `Foo`, we could first use `unifySubtypes` to upcast any * subtypes of `Foo` in the list to `Foo`. * * The following would not compile, for example: */ //stuff.unifySubtypes[Foo].unique[Foo]
This is a very crude way to point out a fact about the behavior of these methods, and we could assume that we want to make these statements more formal - to test units or regressions, etc.
To give a concrete example of why this might be useful in the context of a Shapeless type library, a few days ago I wrote the following as a quick first attempt at answering this question :
import shapeless._ implicit class Uniqueable[L <: HList](l: L) { def unique[A](implicit ev: FilterAux[L, A, A :: HNil]) = ev(l).head }
If the intention is that this will be compiled:
('a' :: 'b :: HNil).unique[Char]
Until it is:
('a' :: 'b' :: HNil).unique[Char]
I was surprised to find that this unique type implementation for HList does not work, because Shapeless would happily find an instance of FilterAux in the latter case. In other words, the following compilation, although you probably expect it to not be:
implicitly[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]
In this case, what I saw was a mistake — or at least something — a mistake — and it has since been fixed .
More generally, we can assume that you want to check the type of invariant that was hidden in my expectations regarding how FilterAux should work with something like unit test - oddly enough, because it might seem like a test type , like this one, with all the recent debates about the relative dignity of types versus tests.
My question
The problem is that I don’t know of any testing framework (for any platform) that allows the programmer to say that something should not be compiled.
One approach I can imagine for the FilterAux case is to use an old trick with an implicit argument with a null value :
def assertNoInstanceOf[T](implicit instance: T = null) = assert(instance == null)
So that you can write the following in unit test:
assertNoInstanceOf[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]
The following would be more convenient and expressive:
assertDoesntCompile(('a' :: 'b' :: HNil).unique[Char])
I want this. My question is: does anyone know of any test library or framework that supports anything remotely, like this is perfect for Scala, but I will agree to something.