DEV Community

Cover image for Utilizing Scala Cats to improve database access code
Senjin Hajrulahovic
Senjin Hajrulahovic

Posted on

3 2

Utilizing Scala Cats to improve database access code

Let start with something familiar. If you worked with scala for some time you most likely came across scala.concurrent.Future#sequence and scala.concurrent.Future#traverse.

Here is a simplified method signature of these two methods:

def traverse[A, B](items: Seq[A])(f: A => Future[B]): Future[Seq[B]]
def sequence[A](items: Seq[Future[A]]): Future[Seq[A]]
Enter fullscreen mode Exit fullscreen mode

cats.Traverse is an abstraction which embodies the operation scala.concurrent.Future#traverse but is more general. Since in addition to the function argument type A and return type B, the context type of both Seq and Future further generalized:

trait Traverse[F[_]] {
  def traverse[G[_], A, B](fa: F[A])(f: A => G[B]): G[F[B]]
}
Enter fullscreen mode Exit fullscreen mode

If you're using a newer version of slick for database access you're most likely familiar with DBIO. There are often cases when you have a collection of some sort and want to execute a database action for each of the elements in the collection.
Since DBIO is somewhat similar to Future we could write:

def f[A](a:A): DBIO[B] = ???

val b: DBIO[Seq[B]] = DBIO.sequence(items.map(f))
Enter fullscreen mode Exit fullscreen mode

or if we lack documentation awareness we could event end up writing:

items.foldLeft(DBIO.successful(Seq()) {
  (acc, next) => acc.flatMap(a => f(next).map(i => acc :+ i)
}
Enter fullscreen mode Exit fullscreen mode

But if we utilize slickcats we can simply write:

items.traverse(f)
Enter fullscreen mode Exit fullscreen mode

But if you try to use this approach without the proper dependencies you'll see that the compilers complains about missing implicit instances for DBIO.

In order to fix that you have to add following dependency:
https://github.com/RMSone/slick-cats
and add following import to your class:

import com.rms.miu.slickcats.DBIOInstances._
Enter fullscreen mode Exit fullscreen mode

Depending on how far you are in you functional programming journey you'll know that cats.Traverse is a special kind of functor which requires a type constructor with a single type argument.

If the methods you want to use together with slickcats return DBIOAction[+R, +S <: NoStream, -E <: Effect] or some other related type which has more than one type parameter the compiler will complain. In these situation you'll have to help the compiler a bit by either changing the method signature to DBIO or you'll have to cast it to DBIO explicitly.

This is just an example. slickcats has typeclass instances which can help you to write more readable database access code.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Postgres on Neon - Get the Free Plan

No credit card required. The database you love, on a serverless platform designed to help you build faster.

Get Postgres on Neon

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay