If you are Scala, Java, C# or similar strongly typed language user, there is a high chance that you like types. You like the assurance that the stuff that you pass around meets the contract. If different types hold common traits then you would probably create a common subclass.

But what happens when those constraints become an overhead?

Hierarchy creates a good reasoning of the domain - you can eat an apple because it’s a fruit.

Shapeless breaks the strict typing constraints and allows any kind of transformations and conversions - and regardless of whether an apple is a fruit, it’s made of sugar, water and some organic carbohydrates, therefore I can make it a mango.

Generic conversions

Whilst Shapeless offers a wide range of utility functions, generics is one of the first basic examples. Imagine we have two objects that have no common hierarchy but still hold common traits. A person and a building both can have a name or age but they are not related to each other.

case class Person(name: String, age: Int)
case class Building(name: String, age: Int)

val person = Person("Arturs", 100)
val house = Building("River House", 1337)

Because their classes are completely irrelevant to each other, we can strip those classes off the objects and put in an empty shell.

val genericPerson = Generic[Person].to(person)
val genericHouse = Generic[Building].to(house)

Now that they both don’t hold any relation to their initial class information, we can use the arguments and apply them to any other classes.

Let’s transform Arturs into a building.

val artursHouse = Generic[Building].from(genericPerson)
>> Building("Arturs", 100)

What’s happening behind the scene is a simple transformation from a concrete class to an HList.

HList is just a hollow list that holds information of the type and the value of every input parameter. Usually you would have a List[T] with a type T applied on a top; HList is a list that with different types applied on each element instead.

Now that we have a list of types and values, we can construct any other concrete object that could be made of those values - ie. Person -> HList -> Building.

Shapeless at OVO

As you might have guessed, we do not use Shapeless only to transform buildings, apples and mangos. We, unfortunately if you may, must interact with the industry governing bodies using CSV formatted hierarchical files.

Those files hold various customer information such as meter technical details, submissions, estimates and lifecycle events. Each CSV file has a complex hierarchical schema with optional fields, grouping, validation rules and different data types - all of that must be parsed and serialised.

OVO Energy settlement process

We will cover this process and the technical challenges that follow in a different blog post.

Coffee with Developers: Shapeless

Watch our first episode of Coffee with Developers video blog where Viktor and Chris discuss some weaknesses and advantages of using Shapeless. Subscribe to our Youtube channel and be the first to see our next episodes!