David Przybilla David Przybilla - 4 months ago 56
Scala Question

Scala with Cats - Cartesian + Validated

I'm doing a simple exercise from the book

Advanced scala with cats
on my own.

I want to use

this works
type ValidatedString = Validated[ Vector[String], String]

/* this doesnt work*/
type Result[A] = Validated[List[String], A]
f(somevariable)//returns Result[String],
g(somevariable)//returns Result[Int],
).map(User.tupled) // creates an user from the returned string, int

Im completely clueless. Any hints ?
Im getting :

could not find implicit value for parameter instance: cats.Cartesian[Result]


Without seeing your imports I'd guess the issue is that you're missing a Semigroup instance for List (or Vector—it's not clear which you want to use), since the following works for me:

import cats.Cartesian, cats.data.Validated, cats.implicits._

type Result[A] = Validated[List[String], A]


You could replace the cats.implicits._ part with the following:

import cats.instances.list._
import cats.syntax.validated._

…but I'd suggest starting with cats.implicits._.

The problem here is that Validated accumulates failures when you combine two instances with product, and what "accumulates" means in a particular context is determined by a Semigroup instance for the invalid type that tells you how to "add" two invalid values together.

In the case of List (or Vector), concatenation makes sense for this accumulation operation, and Cats provides the concatenation Semigroup for any List[A], but in order to get it to be applied here you have to explicitly import it (either from cats.implicits or from cats.instances.list).