Say I have the following functions:
case class ErrA(msg: String)
case class ErrB(msg: String)
def doA(): Either[ErrA, Int] = Right(2)
def doB(): Either[ErrB, Int] = Right(3)
ErrA
and ErrB
are unrelated types and are not actually declared in the same file outside of this example. They cannot be easily made to inherit from a common type.
I would like to introduce a new type that would represent both error types:
sealed trait ErrAOrB
case class ErrAWrapper(e: ErrA) extends ErrAOrB
case class ErrBWrapper(e: ErrB) extends ErrAOrB
And then write the following function using a for comprehension:
def doAplusB(): Either[ErrAOrB, Int] =
for (a <- doA().right;
b <- doB().right) yield a + b
Is there any way to get the compiler to implicitly convert those specific Either
types to the common Either[ErrAOrB, Int]
type?
For instance:
implicit def wrapA[T](res: Either[ErrA, T]): Either[ErrAOrB, T] = res.left.map(ErrAWrapper(_))
implicit def wrapB[T](res: Either[ErrB, T]): Either[ErrAOrB, T] = res.left.map(ErrBWrapper(_))
But that doesn't work because the implicit conversion gets applied only to the final expression in the for comprehension, and then the compiler has to bind it to doA
and since types ErrA
and ErrAOrB
are unrelated the best it can do is to make the generics make sense is to use Object
which is not compatible with the expected type.