Can someone explain to me what the Shapeless library is for?

loyalflow picture loyalflow · Feb 12, 2014 · Viewed 12.2k times · Source

Can someone explain to me in simple terms what the Shapeless library is for?

Scala has generics and inheritance functionality so I'm a bit confused what Shapeless is for.

Maybe a use case to clarify things would be helpful.

Answer

Kevin Wright picture Kevin Wright · Feb 12, 2014

It's a little hard to explain, as shapeless has a wide range of features; I'd probably find it easier to "explain, in simple terms, what variables are for". You definitely want to start with the feature overview.

Broadly speaking, shapeless is about programming with types. Doing things at compile-time that would more commonly be done at runtime, keeping precise track of the type of each element in a list, being able to translate from tuples to HLists to case classes, creating polymorphic functions (as opposed to methods), etc.

A typical usage scenario would go something like:

  • Read a bunch of values from somewhere into a List
  • perform a type-safe cast of that List into an HList
  • map over that HList with a polymorphic function that e.g. normalises values
  • convert the 3rd element (which is statically known to be an Int) into a 0-padded string
  • construct a case class using values from the HList

For reference, an HList will have a precise type, such as Int :: String :: Boolean :: HNil (yes, that really is a single type) where everything is pinned down and the size is fixed. So you either need to know at compile time exactly what will be going into your HList, or you need the type-safe cast.

If you take the tail of such an HList, you get a String :: Boolean :: HNil, and a compile-time guarantee that the head of this will be a String. Prepending a value to the head will similarly preserve all types involved.

Shapeless also comes with the Generic type class, allowing you to use HList operations on tuples and case classes as well.

The other features I tend to use are:

  • Coproducts, which allow you to statically type a value as being e.g. "a String, Double or Int, but nothing else" (much like Either, but not limited to just two possibilities)

  • Lenses, which simplify working with nested case classes.