Search code examples
scalascala-cats

cats.data.EitherT with traverse


I have a question about using Traverse together with EitherT. Let's say we have a code like this:

def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
  EitherT(Future.successful(try { Right(s.toInt) } catch { case e: 
  NumberFormatException => Left(e)}))
}

List("1", "2").traverse(validate)

Unfortunately this code does not compile, because we are missing something:

error: could not find implicit value for evidence parameter of type cats.Applicative[G] List("1", "2").traverse(validate)

I tried to look this up and found for example this answer: Switching between EitherT and Validation to accumulate error or traverse or Validation versus disjunction

So it seems some solution could exists. But the problem is that both of them are using traverseU, which is no longer an option in scala 2.12. So how can this be done please?

EDIT This is the code including imports:

import cats.data.EitherT
import cats.syntax.traverse._
import cats.instances.list._
import cats.instances.future._
import scala.concurrent.ExecutionContext.global

import scala.concurrent.Future

def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
  EitherT(Future.successful(try { Right(s.toInt) } catch { case e:
    NumberFormatException => Left(e)}))
}

List("1", "2").traverse(validate)

Solution

  • import cats.{Applicative, Monad}
    import cats.data.EitherT
    import cats.syntax.traverse._
    import cats.instances.list._
    import cats.instances.future._
    
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.Future
    
    def validate(s: String): EitherT[Future, NumberFormatException, Int] = {
        EitherT(Future.successful(try { Right(s.toInt) } catch { case e: NumberFormatException => Left(e) }))
      }
    
    type Tmp[T] = EitherT[Future, NumberFormatException,T]
    List("1", "2").traverse[Tmp, Int](validate)
    

    So this is how it works to me. I had to create new type.