universitarias trabajo soluciones sociales que problemas presentan plan lineas lectura las falta escolar consecuencias comite bibliotecas biblioteca acciones accion scala shapeless

scala - trabajo - problemas que presentan las bibliotecas



¿Puede alguien explicarme para qué sirve la biblioteca Shapeless? (3)

¿Puede alguien explicarme en términos simples para qué sirve la biblioteca Shapeless?

Scala tiene genéricos y funcionalidad de herencia, así que estoy un poco confundido por lo que Shapeless es.

Tal vez un caso de uso para aclarar las cosas sería útil.


Es un poco difícil de explicar, ya que sin forma tiene una amplia gama de características; Probablemente me resulte más fácil "explicar, en términos simples, para qué son las variables". Definitivamente desea comenzar con la descripción general de la función .

En términos generales, sin forma se trata de programar con tipos. Hacer cosas en tiempo de compilación que normalmente se realizarían en tiempo de ejecución, manteniendo un seguimiento preciso del tipo de cada elemento en una lista, pudiendo traducir de tuplas a HLists a clases de casos, creando funciones polimórficas (a diferencia de los métodos), etc.

Un escenario de uso típico sería algo así como:

  • Lea un montón de valores de algún lugar en una List
  • realizar un molde seguro de tipo de esa List en una HList
  • mapa sobre esa lista HList con una función polimórfica que, por ejemplo, normaliza los valores
  • Convierta el tercer elemento (que se sabe estáticamente que es un Int ) en una cadena de 0 rellenos
  • construir una clase de caso usando valores de HList

Como referencia, una HList tendrá un tipo preciso, como Int :: String :: Boolean :: HNil (sí, que realmente es un solo tipo) donde todo está anclado y el tamaño es fijo. Por lo tanto, o necesita saber en el momento de la compilación exactamente lo que ingresará en su HList, o si necesita un modelo seguro.

Si tomas la tail de una lista HList, obtienes una String :: Boolean :: HNil y una garantía en tiempo de compilación de que el jefe de esto será una String . El anteponer un valor al encabezado conservará de manera similar todos los tipos implicados.

Shapeless también viene con la clase de tipo Generic , lo que le permite usar operaciones HList en tuplas y clases de casos también.

Las otras características que tiendo a usar son:

  • Coproducts , que le permiten escribir estáticamente un valor como, por ejemplo, "un String , Double o Int , pero nada más" (muy parecido a Either , pero no limitado a solo dos posibilidades)

  • Lenses , que simplifican el trabajo con clases de casos anidados.


Todo en Shapeless tiene dos cosas en común:

Primero, no está en la biblioteca estándar de Scala, pero podría decirse que debería estarlo. Por lo tanto, preguntarse para qué sirve Shapeless es un poco como preguntar con la biblioteca estándar de Scala. Es para todo . Es una bolsa de sorpresas.

(Pero no es una bolsa de sorpresas totalmente arbitraria, porque :)

En segundo lugar, todo en Shapeless proporciona mayor control y seguridad en tiempo de compilación . Nada en Shapeless (¿en qué puedo pensar?) Realmente "hace" algo en tiempo de ejecución. Toda la acción interesante ocurre cuando se compila tu código. El objetivo siempre es aumentar la confianza de que si el código compila en absoluto, no se bloqueará o hará lo incorrecto en el tiempo de ejecución. (De ahí esta notable ocurrencia: https://twitter.com/mergeconflict/status/304090286659866624 )

Hay una buena introducción a lo que se trata la programación a nivel de tipo, con enlaces a recursos adicionales, en https://.com/a/4443972/86485 .


Ver una HList es algo que puede parecer desconcertante hasta que intente trabajar con tipos y delegar o activar tipos. Eche un vistazo a lo siguiente:

val myList = 1 :: 2 :: "3" :: fred :: Nil

¿Cuál es el tipo de myList aquí? Si tuviera que inspeccionarlo, vería que era de tipo List[Any] . Eso no es muy útil. Lo que es aún menos útil es si traté de usar la siguiente función PartialFunction[Any] para map sobre ella:

myList.map{ case x: Int => x case x: String => Int.parseInt(x) }

En tiempo de ejecución, esto podría arrojar un MatchError porque en realidad no te he dicho qué tipo es fred . Podría ser de tipo Fred .

Con una HList puede saber en tiempo de compilación si no ha capturado uno de los tipos de esa lista. En lo anterior, si hubiera definido myList = 1 :: 2 :: "3" :: fred :: HNil cuando myList = 1 :: 2 :: "3" :: fred :: HNil al tercer elemento, su tipo sería String y esto se conocería en tiempo de compilación.

Como dice @KevinWright, hay algo más que eso con Shapeless, pero HList es una de las características definitorias de la biblioteca.