-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add recoverF and mapF to EitherT #1643
Comments
Sounds good to me so far. 👍 to making a PR. |
@edmundnoble I'm on it. |
I take it that the |
@djspiewak It has a Monad instance, not a MonadError for F so there is no recovery for F. I just checked: implicit def catsDataMonadErrorForEitherT[F[_], L](implicit F0: Monad[F]): MonadError[EitherT[F, L, ?], L] =
new EitherTMonadError[F, L] { implicit val F = F0 }
private[data] trait EitherTMonadError[F[_], L] extends MonadError[EitherT[F, L, ?], L] with EitherTMonad[F, L] {
def handleErrorWith[A](fea: EitherT[F, L, A])(f: L => EitherT[F, L, A]): EitherT[F, L, A] =
EitherT(F.flatMap(fea.value) {
case Left(e) => f(e).value
case r @ Right(_) => F.pure(r)
})
override def handleError[A](fea: EitherT[F, L, A])(f: L => A): EitherT[F, L, A] =
EitherT(F.flatMap(fea.value) {
case Left(e) => F.pure(Right(f(e)))
case r @ Right(_) => F.pure(r)
})
def raiseError[A](e: L): EitherT[F, L, A] = EitherT.left(F.pure(e))
override def attempt[A](fla: EitherT[F, L, A]): EitherT[F, L, Either[L, A]] = EitherT.right(fla.value)
override def recover[A](fla: EitherT[F, L, A])(pf: PartialFunction[L, A]): EitherT[F, L, A] =
fla.recover(pf)
override def recoverWith[A](fla: EitherT[F, L, A])(pf: PartialFunction[L, EitherT[F, L, A]]): EitherT[F, L, A] =
fla.recoverWith(pf)
} |
Oh, yeah that's basically not what we want. :-D I guess there are actually two possible |
@djspiewak I had been looking around in code and I had some use cases for EitherT and Kleisli where there was a need to recover from F. I had a failed PR on Kleisli about this (#1601). The only catch about the solution to recover Kleislis is that you have to define a type alias for the ApplicativeError instance to get selected: Since that idea stuck in my mind and considering that for both cases there is no way to recover from F, maybe this proposal can point us to a proper solution. Is it worth the try then @djspiewak? |
@leandrob13 Did you still have to alias even with |
@djspiewak In the test that I did after the guys pointed out that alternative, yes. The point is that I wanted Kleisli to recover without the work around. |
Well, |
@djspiewak I didn't mean the |
Oh, I see what you mean. I think that probably stems from the fact that |
@djspiewak now I know why, thanks! And I forgot that by the time I did the failed kleisli pr unapply was not removed yet. I will finish my proposal for EitherT and maybe I could have another shot at Kleisli recoverF |
Issue addressed in #1644 |
I have been dealing with use cases where there is an
EitherT[Future, X, Y]
and there is the need to recover from a failed future.If I want to recover from the future that failed and keep the EitherT context, would have to do:
I want to be able to just do
EitherT(fe("not an int")).recoverWith { ... }
obviously not only for futures but with any F that has a ApplicativeError instance.Is it a good idea to add a recoverF and recoverFWith functions to EitherT? I have been considering adding a mapF also.
The text was updated successfully, but these errors were encountered: