Search code examples
scalascala-catsmonad-transformers

EitherT not properly upcasting to common trait super type (Scala 3)


When chaining a for comprehension with EitherT, the compiler is having issues upcasting my errors to their common ancestor type.

I have the following type definitions in my code:

sealed trait Error
object Error:
  case object Error1 extends Error
  case class Error2(someParams) extends Error

So far so good. I then had this trait where I expose this stuff:

trait SomeInterface[F[_]]:
  def someMethod(params): F[Either[Error1.type, Type1]]
  def otherMethod(params): F[Either[Error2, Type2]]

Then inside my logic I'm chaining them in this way:

for {
  t1 <- EitherT(someMethod)
  t2 <- EitherT(otherMethod)
yield t2

This should work in theory, but I'm getting the following error:

Found: EitherT[F, Error2, Type2]
Expected: EitherT[F, Error1.type, Any]

I already tried changing my interfaces so that they return the common type, but then it has trouble casting it when I implement.

I also tried passing type parameters in the EitherT constructor, but same results.


Solution

  • Not a great FP expert to be honest so I'm not sure whether my solution is the "clean" one, but whenever I had this kind of problem I fixed by importing cats.syntax.bifunctor.* and calling leftWiden[Error] on the EitherT.