Quelqu'un peut-il m'expliquer en termes simples à quoi sert la bibliothèque Shapeless?
Scala a des fonctionnalités génériques et d'héritage, donc je suis un peu confus à quoi sert Shapeless.
Peut-être qu'un cas d'utilisation pour clarifier les choses serait utile.
C'est un peu difficile à expliquer, car informe a un large éventail de fonctionnalités; Je trouverais probablement plus facile "d'expliquer, en termes simples, à quoi servent les variables". Vous voulez certainement commencer par aperçu des fonctionnalités .
De manière générale, informel concerne la programmation avec des types. Faire des choses au moment de la compilation qui se feraient le plus souvent au moment de l'exécution, garder une trace précise du type de chaque élément dans une liste, être capable de traduire des tuples en listes HL en classes de cas, en créant des fonctions polymorphes (par opposition aux méthodes), etc.
Un scénario d'utilisation typique se présenterait comme:
List
List
dans un HList
HList
avec une fonction polymorphe qui, par exemple normalise les valeursInt
) en une chaîne à 0 remplissagePour référence, un HList
aura un type précis, tel que Int :: String :: Boolean :: HNil
(oui, vraiment est un seul type) où tout est épinglé et la taille est fixe. Vous devez donc savoir au moment de la compilation exactement ce qui se passera dans votre HList, ou vous avez besoin de la fonte de type sécurisé.
Si vous prenez le tail
d'un tel HList, vous obtenez un String :: Boolean :: HNil
, et une garantie à la compilation que la tête de ceci sera un String
. Ajouter une valeur à la tête préservera également tous les types impliqués.
Shapeless est également fourni avec la classe de type Generic
, vous permettant également d'utiliser les opérations HList sur les tuples et les classes de casse.
Les autres fonctionnalités que j'ai tendance à utiliser sont:
Coproducts
, qui vous permet de taper statiquement une valeur comme étant par exemple "a String
, Double
ou Int
, mais rien d'autre" (un peu comme Either
, mais pas limité à seulement deux possibilités)
Lenses
, ce qui simplifie le travail avec les classes de cas imbriquées.
Regarder un HList
est quelque chose qui peut sembler déroutant jusqu'à ce que vous essayiez de travailler avec des types et de déléguer ou d'activer des types. Jetez un œil à ce qui suit:
val myList = 1 :: 2 :: "3" :: fred :: Nil
Quel est le type de myList
ici? Si vous deviez l'inspecter, vous verriez qu'il était de type List[Any]
. Ce n'est pas très utile. Ce qui est encore moins utile, c'est que si j'essaie d'utiliser le PartialFunction[Any]
Pour map
par-dessus:
myList.map{
case x: Int => x
case x: String => Int.parseInt(x)
}
Au moment de l'exécution, cela pourrait générer un MatchError
parce que je ne vous ai pas vraiment dit de quel type fred
. Il pourrait être de type Fred
.
Avec un HList
, vous pouvez savoir directement au moment de la compilation si vous n'avez pas réussi à capturer l'un des types de cette liste. Dans ce qui précède, si j'avais défini myList = 1 :: 2 :: "3" :: fred :: HNil
Lorsque j'ai accédé au 3e élément, son type serait String
et cela serait connu au moment de la compilation.
Comme l'indique @KevinWright, il y a plus que cela avec Shapeless mais HList
est l'une des caractéristiques qui définissent la bibliothèque.
Tout dans Shapeless a deux choses en commun:
Tout d'abord, il ne se trouve pas dans la bibliothèque standard Scala, mais devrait sans doute l'être. Par conséquent, demander à quoi sert Shapeless est un peu comme demander avec le Scala la bibliothèque standard est pour! C'est pour tout . C'est un sac à main.
(mais ce n'est pas un sac à main totalement arbitraire, parce que :)
Deuxièmement, tout dans Shapeless offre une vérification et une sécurité accrues au moment de la compilation . Rien dans Shapeless (auquel je peux penser?) Ne "fait" quoi que ce soit à l'exécution. Toutes les actions intéressantes se produisent lorsque votre code est compilé. L'objectif est toujours d'augmenter la confiance que si votre code se compile, il ne se bloquera pas ou ne fera pas la mauvaise chose à l'exécution. (D'où cette plaisanterie notable: https://Twitter.com/mergeconflict/status/304090286659866624 )
Il y a une belle introduction à ce qu'est la programmation au niveau du type, avec des liens vers d'autres ressources, à https://stackoverflow.com/a/4443972/86485 .