Latest blog posts

From Scala 2 shapeless to Scala 3

Scala, Scala 3, shapeless

In this post I’d like to discover Scala 3 generic programming abilities. Scala 3 provides a lot of new features, and generic programming is the one of the areas where we have a lot of changes. I assume that you have used shapeless with Scala 2, but if not, I’ll try to explain things in this post. However I’d recommend to read this post before if you don’t even know what shapeless is.

Tuples in Scala 3

Let’s take a look at tuples in Scala 3. In previous versions of Scala we had the famous Tuple1 .. Tuple22 classes defined like:

final case class Tuple2[+T1, +T2](_1: T1, _2: T2) 
    extends Product2[T1, T2] 
    with Product 
    with Serializable

These classes are available in Scala 3 too, but there are another classes for tuples:

sealed trait Tuple extends Product
object EmptyTuple extends Tuple
trait NonEmptyTuple extends Tuple
case class [+H, +T <: Tuple] *:(head: H, tail: T) extends NonEmptyTuple

I simplified the code a little bit, but the idea is the same. This is something new in the Scala library, but it looks very familiar. Actually it’s a list with different types of its’ elements. This called the Heterogeneous list, or HList! In Scala 2 we had HLists in shapeless, and also in some other libraries. Having heterogeneous lists in the standard library makes a lot of sense, and now we don’t need any other HList implementation. Scala 3 tuples has a lot of useful functions, for example they can be converted to List, be concatenated, zipped, etc.:

scala> val t = (5, "String", 3d, false)
val t: (Int, String, Double, Boolean) = (5,String,3.0,false)

scala> t.toList
val res0: List[Tuple.Union[t.type]] = List(5, String, 3.0, false)

scala> val x = t.drop(2)
val x: (Double, Boolean) = (3.0,false)

scala> t ++ x
val res1: Int *: String *: Double *:
  scala.Tuple.Concat[Boolean *: scala.Tuple$package.EmptyTuple.type, x.type]
    = (5,String,3.0,false,3.0,false)

Moreover, Scala 3 provides mechanisms similar to shapeless Generics making possible to convert from algebraic data types (if you are not familiar with algebraic data types, to understand further examples you might think that it’s just case classes) to tuples and back. Let’s take a look at these features.

Tuples from case classes

The Tuple companion object contains method fromProductTyped which allows us to construct tuple from a case class:

scala> case class Foo(a: String, b: Int)
// defined case class Foo

scala> Tuple.fromProductTyped(Foo("test", 5))
val res2: (String, Int) = (test,5)

With this knowledge we can try to implement SqlSaver from “Getting started with shapeless” post for Scala 3. So, let’s do it. The type class definition itself is unchanged:

trait SqlSaver[A] {
  def save(statement: PreparedStatement, idx: Int)(a: A): Int

However, there is a new syntax for implicits in Scala 3. When we need to use an implicit instance we use using keyword. So, now the summoner method will look like:

object SqlSaver {
  def apply[T](using ss: SqlSaver[T]): SqlSaver[T] = ss

When we need to declare an instance of type class (or any other implicit), we use given keyword. With this new syntax instances of SqlSaver for primitive types become:

object SqlSaver {
  // ...
  given SqlSaver[Int] = createSimpleSaver((a, s, i) => s.setInt(i, a))
  given SqlSaver[String] = createSimpleSaver((a, s, i) => s.setString(i, a))
  given SqlSaver[Double] = createSimpleSaver((a, s, i) => s.setDouble(i, a))
  given SqlSaver[BigDecimal] = createSimpleSaver((a, s, i) => s.setBigDecimal(i, a.underlying))
  given SqlSaver[LocalDateTime] = 
    createSimpleSaver((a, s, i) => s.setTimestamp(i, Timestamp.valueOf(a)))

In this example we created anonymous instances, but it’s also possible to give names to the type class instances, e.g.:

  given intSaver: SqlSaver[Int] = createSimpleSaver((a, s, i) => s.setString(i, a))

Now, let’s implement SqlSaver instances for tuples. As it was before for HNil (empty HList), for the empty tuple it just does nothing:

  given SqlSaver[EmptyTuple] = createSaver((_, _, i) => i)

For non-empty tuple we need SqlSaver for head, to save left tuple member and SqlSaver for the tail, like we did before for :: (non-empty HList):

  given [H, T <: Tuple](using hSaver: SqlSaver[H], tSaver: SqlSaver[T]): SqlSaver[H *: T] = 
    new SqlSaver[H *: T] {
      override def save(statement: PreparedStatement, idx: Int)(t: H *: T): Int = {
        val next =, idx)(t.head), next)(t.tail)

Here, we created instance for tuple dependent on the instances for the H and T via using keyword.

Finally, we can create instance for Products, which will convert a case class to tuple, and then call SqlSaver for the tuple to really save the data. However, to do it we need to know the exact tuple type. For example, if the product is case class Foo(a: String, b: Int) then the tuple type will be (String, Int), or that’s the same String *: Int *: EmptyTuple. In shapeless for Scala 2, we used Generic to convert ADTs to and from HLists. It also was a type link between ADTs and their HList representations. In Scala 3, we have class Mirror to connect products and coproducts with tuples both on the type and the value level.

To achieve that Mirror trait contains several type members. The MirroredElemTypes is a tuple type we are looking for. Bearing this in mind, we can connect the mirror with the SqlSaver in the using part of the type class instance declaration:

import scala.deriving.Mirror
// ...

  given [P <: Product](using m: Mirror.ProductOf[P],
                            ts: SqlSaver[m.MirroredElemTypes]
                      ): SqlSaver[P] = new SqlSaver[P] {
    override def save(statement: PreparedStatement, idx: Int)(t: P): Int =, idx)(Tuple.fromProductTyped(t))

Here you can see another new cool feature of Scala 3. Previously we had to use Aux pattern to make types depend on each other. Now, we can just use type members in other function parameters or even as a result type.


Scala 3 brings us a lot of new features. Personally I like the way the language is evolving. Even if some things a bit controversial most of the stuff makes Scala more readable, and gives us tools to build standard solutions for standard problems. Typelevel programming in general is a complex topic, but the new code looks a bit simpler, and also it doesn’t require external dependencies.

sbt-git-flow-version announcement

Scala, sbt, git, sbt-git-flow-version

I’d like to announce my new project called sbt-git-flow-version. As you might guess it’s a plugin for sbt. The goal of the project is set your sbt build version according to git flow rules.

I found that for big or medium size teams git flow is quite practical. What I didn’t like about it, is that it requires to change the version all the time you change the branch in your repository. At some point I took responsibilities of release engineer in our team. Since I’m very lazy to do all of this styff I came up with some Scala code in the project catalog of my current working project. Later I rewrote it as an sbt plugin.

So, what can it do for you?

Continue reading

BeanPurée 0.2 release announcement

Scala, Java, shapeless, BeanPurée

I’m happy to announce the second release of BeanPurée library.

The main goal of this release is to make BeanConverter more intelligent. Previously, it required you to have the same type for the corresponding fields in a bean and a product. If there are Java number classes in your beans, it’s possible you don’t want to use it in your Scala code. Instead, you would like to use Options, or you may know that these values are never null.

Now BeanConverter can do these kinds of transformations for you.

JavaTypeMapper type class was introduced to acheive that. It provides two-way conversions for the following cases:

  • Java number class to Scala type. E.g. Integer to Int, or java.math.BigDecimal to scala.math.BigDecimal. If Java value is null it throws NullPointerException.
  • A class T to an Option[T]. Wraps nullable to Option.
  • A class T for which an instance of JavaTypeMapper to class U is available to an Option[U]. For example it is used to convert Integer to Option[Int].
  • HList of the elements which can be mapped with JavaTypeMappers, to HList of mapped values.

If you want to have a previous behavior from BeanConverter use StrictBeanConverter class.

Introducing BeanPurée

Scala, Java, shapeless, BeanPurée

As a Scala developer I prefer to use Scala libraries rather than Java ones for my code. However, it is not always possible. Sometimes I might not find a required library, or I just have to use some legacy code I already have. Even though Scala runs on a JVM and is fully compatible with Java, the languages have different ideologies, different code styles and sometimes different API’s. Thus, in Scala it is preferable to use immutable case classes for the data modeling. However, in Java the common building blocks are JavaBeans, which are mutable. Another problem is that a lot of Scala libraries expect case classes. Even if they work with JavaBeans, usually you have to write some boilerplate code.

So, quite often it is easier to have a separate model in your Scala code, and converters between Java model classes and Scala ones.

BeanPurée is a library that helps you to automate this process. And it helps you to do even more, because it’s a bridge from JavaBeans to shapeless.

Continue reading

Generating SQL queries with shapeless

Scala, shapeless

In the previous posts we created the SqlSaver class which can set values into the prepared statement. It assumes that the SQL request is correct and the parameters are in the required order (in the order they are defined in the model). What if the model class is changed? If the query is not updated we’ll get a runtime error, since the fields order in the query and the order of calls performed by SqlSaver are not the same anymore. So, it would be nice to generate SQL queries as well. Something like:

val query = StatementGenerator[Sale].insert(tableName)
val statement = connection.prepareStatement(query)
SqlSaver[Sale](statement, 1)(sale)

Let’s try to implement it with shapeless.

Continue reading

Firefox ESR and XMonad

XMonad, Gentoo

If you are XMonad and Firefox ESR user, just like me, you might know that there is a problem with full screen videos playback. A video hangs and you cannot close it. All you can do is just to kill Firefox. It’s already fixed in the main line, but it looks like they don’t want to port the patch to ESR version.

Fortunately the patch is not too big and I adopted it for the ESR version. Here is it:

Continue reading

Pagination with Hakyll

Hakyll, Haskell

Yesterday I realized that there are more than ten posts in my blog. Not so many for more than a year, but quite a lot for the index page. The simplest solution is to just limit amount of posts with take function, and write something like “more posts in the archives”. But I prefer to have pagination for the index page. Hakyll has built-in support for pagination in the module Hakyll.Web.Paginate. There is a very nice manual about how to use it in this blog post.

Unfortunately, Paginate provides only first/previous/current/next/last functionality. It’s quite common to have only “Older posts” and “Newer posts” buttons for blogs, but I’d like to have a list of all pages in the Bootstrap pagination component. So, it’s time to write some Haskell code (of course you need to write code to add the standard Paginate, but I’m going to write a little bit more).

Continue reading

Fixing bugs in SqlSaver

Scala, shapeless

In the previous post I created SqlSaver class. Later, playing with it, I found that it has several bugs.

First of all, it doesn’t work properly with nested classes. Let’s start with a test:

case class SaleRecord(id: Int, sale: Sale, seller: String)

it should "save nested case classes" in {
  val date =
  SqlSaver[SaleRecord].save(stm, 6)(
    SaleRecord(1, Sale("bar", date, 42), "Shop")
  ) should equal(11)

  verify(stm).setInt(6, 1)
  verify(stm).setString(7, "bar")
  verify(stm).setTimestamp(8, Timestamp.valueOf(date))
  verify(stm).setBigDecimal(9, java.math.BigDecimal.valueOf(42))
  verify(stm).setString(10, "Shop")

Unfortunately it doesn’t compile:

[error] SqlSaverTest.scala:38: diverging implicit expansion for type SqlSaver[LocalDateTime :: BigDecimal :: HNil]
[error] starting with method hlistSaver in object SqlSaver
[error]    SqlSaver[SaleRecord].save(stm, 6)(
[error]            ^
Note: here and later I rewrote HLists into the infix form, for readability.
Continue reading

Getting started with shapeless

Scala, shapeless

Sooner or later, every Scala programmer tries to study shapeless, Scalaz, Cats and other libraries, which are not designed to solve one small problem, but were created to explode your brain change the way you are writing your code, make it safer and at the same time more generic. I’ve tried to study shapeless several times, but the main problem is that there are no entry point. There are a lot of things and all of them are quite difficult.

Finally I decided to solve some small problems with shapeless to find some patterns and scenarios of how to use it. So, what kind of problems can I use? Shapeless is really useful when you want to process your data in a type safe generic way.

The problem I’d like to solve in this post is type safe saving arbitrary case class into an SQL statement. E.g:

case class Sale(name: String, date: LocalDateTime, price: BigDecimal)

SqlSaver[Sale].save(st, 1)(Sale("Banana",, 55))

This call will call the PreparedStatement methods for each field, taking into account the field type. In this example it should be:

st.setTimestamp(2, Timestamp.valueOf(
st.setBigDecimal(3, sale.price.underlying)
Continue reading

Scala type variance and Java collections

Scala, collections, Java

Converting Scala collections to Java and backward

It’s quite often that we need to use a Java API from Scala. And these usages occurs even more often when you have modules written in Java in your Scala project. The most common problem is to pass Java collections to Scala API and Scala collections to Java. Fortunately, Scala library provides bidirectional implicit converters between Scala and Java collections. There are two classes JavaConverters and JavaConversions which provide the same functionality but in a different way.

Assume we have a Java service:

interface Message {
    String getText();
    LocalDateTime getDate();

public class JavaService {
    void handleMessages(List<Message> messages) {
            .sorted((o1, o2) -> o1.getDate().compareTo(o2.getDate()))
            .forEach(m ->
                    + " " + m.getText()));

    List<Message> generateMessages(int n) {
        return IntStream.range(0, n)
                .mapToObj(i -> new JavaMessage(String.valueOf(i),
Continue reading