Le problème
Quand je travaille avec les bibliothèques qui prennent en charge au niveau du type de programmation, il m'arrive souvent d'écrire des commentaires comme suit (à partir d' un exemple présenté par Paul snively a à Boucle Étrange 2012):
// But these invalid sequences don't compile:
// isValid(_3 :: _1 :: _5 :: _8 :: _8 :: _2 :: _8 :: _6 :: _5 :: HNil)
// isValid(_3 :: _4 :: _5 :: _8 :: _8 :: _2 :: _8 :: _6 :: HNil)
Ou ce, à partir d' un exemple dans l' Informe référentiel:
/**
* 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]
C'est une façon très difficile d'en indiquant un certain effet sur le comportement de ces méthodes, et nous pourrions l'imaginer vouloir faire ces affirmations plus formelle-pour l'unité ou les tests de régression, etc.
Pour donner un exemple concret de quoi cela peut être utile dans le contexte d'une bibliothèque comme Informes, il y a quelques jours, j'ai écrit la suite rapidement une première tentative de réponse à cette question:
import shapeless._
implicit class Uniqueable[L <: HList](l: L) {
def unique[A](implicit ev: FilterAux[L, A, A :: HNil]) = ev(l).head
}
D'où l'intention est que ce sera de la compilation:
('a' :: 'b :: HNil).unique[Char]
Bien que ce ne sera pas:
('a' :: 'b' :: HNil).unique[Char]
J'ai été surpris de constater que cette mise en œuvre d'un type de niveau unique
pour HList
n'ont pas de travail, parce que Informes serait heureux de trouver un FilterAux
exemple dans le dernier cas. En d'autres termes, les éléments suivants devraient compiler, même si vous auriez probablement s'attendre à ne pas:
implicitly[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]
Dans ce cas, ce que je voyais était un bugou au moins quelque chose de bug-ish-et il a depuis été corrigé.
Plus généralement, on peut imaginer vouloir vérifier le type d'invariant qui était implicite dans mes attentes sur la façon dont FilterAux
devrait travailler avec quelque chose comme un test unitaire-aussi bizarre que cela puisse paraître à parler de test au niveau du type de code comme ceci, avec tous les récents débats sur le mérite relatif des types de vs tests.
Ma question
Le problème est que je ne sais pas du tout le genre de framework de test (pour n'importe quelle plate-forme) qui permet au programmeur d'affirmer que quelque chose ne doit pas compiler.
Une approche que je puisse imaginer pour l' FilterAux
cas serait d'utiliser l'ancien implicite-argument-à null par défaut truc:
def assertNoInstanceOf[T](implicit instance: T = null) = assert(instance == null)
Qui permet d'écrire le code suivant dans votre unité de test:
assertNoInstanceOf[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]
Ce qui suit est un diable de beaucoup plus pratique et expressif, bien que:
assertDoesntCompile(('a' :: 'b' :: HNil).unique[Char])
Je veux que ce. Ma question est de savoir si quelqu'un sait de toute bibliothèque de test ou d'un cadre qui prend en charge quelque chose à distance comme elle-idéalement situé pour la Scala, mais je vais me contenter de rien.