web-dev-qa-db-fra.com

Quelqu'un peut-il m'expliquer à quoi sert la bibliothèque Shapeless?

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.

69
loyalflow

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:

  • Lire un tas de valeurs quelque part dans un List
  • effectuer une conversion de type sécurisé de ce List dans un HList
  • mappez ce HList avec une fonction polymorphe qui, par exemple normalise les valeurs
  • convertir le 3e élément (qui est statiquement connu pour être un Int) en une chaîne à 0 remplissage
  • construire une classe de cas en utilisant les valeurs de la HList

Pour 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.

47
Kevin Wright

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.

32
wheaties

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 .

20
Seth Tisue