Looking at the sources of orElse
it seems that it can be naturally generalized as
import scala.language.higherKinds
def onLeft[F[+_],A,B](x: => EitherT[F, A, B])
(y: A => EitherT[F, A, B])
(implicit F: Bind[F]): EitherT[F, A, B] =
{
val g = x.run
EitherT(F.bind(g) {
case -\/(l) => y(l).run
case \/-(_) => g
})
}
This is basically the same thing as swapping left/right and then using monadic binding
def onLeft1[F[+_],A,B](x: => EitherT[F, A, B])
(y: A => EitherT[F, A, B])
(implicit F: Monad[F]): EitherT[F, A, B] =
x.swap.flatMap((a: A) => y(a).swap).swap
but of course the first variant is more efficient (and also a bit more general in F
).