-
-
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 attemptNarrow to ApplicativeErrorOps #2863
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2863 +/- ##
==========================================
- Coverage 94.18% 93.17% -1.01%
==========================================
Files 368 372 +4
Lines 6948 7182 +234
Branches 308 198 -110
==========================================
+ Hits 6544 6692 +148
- Misses 404 490 +86
Continue to review full report at Codecov.
|
@@ -83,6 +86,9 @@ final class ApplicativeErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal | |||
def attempt(implicit F: ApplicativeError[F, E]): F[Either[E, A]] = | |||
F.attempt(fa) | |||
|
|||
def attemptCase[EE](implicit F: ApplicativeError[F, E], tag: ClassTag[EE], ev: EE <:< E): F[Either[EE, A]] = | |||
F.recover(F.map(fa)(_.asRight[EE])) { case e: EE => e.asLeft[A] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that extra inter-dependencies could lead to circular dependencies, perhaps we can by-pass the either
syntax and use this not much longer alternative:
F.recover(F.map(fa)(_.asRight[EE])) { case e: EE => e.asLeft[A] } | |
F.recover(F.map(fa)(x => Right[EE, A](x))) { case e: EE => Left[EE, A](e) } |
b6ba437
to
a75d0f9
Compare
I think this could be useful although I am not quite sure about the name. I am thinking |
@kailuowang renamed to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@@ -83,6 +85,9 @@ final class ApplicativeErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal | |||
def attempt(implicit F: ApplicativeError[F, E]): F[Either[E, A]] = | |||
F.attempt(fa) | |||
|
|||
def attemptNarrow[EE](implicit F: ApplicativeError[F, E], tag: ClassTag[EE], ev: EE <:< E): F[Either[EE, A]] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need a classtag here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EE
would be erased and we wouldn't be able to pattern match on it otherwise @tkroman
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a test with a parameterized type, also demonstrating non-compilation for things like narrowing to List[Int]
when it's actually List[String]
. Since we're skating close to erasure.
@tpolecat I added the test, let me know what you think |
hey @kailuowang, is there anything I can do to get this merged? |
Hi @marcodippy sorry about the delay here, but can I ask one more thing? Now that we dropped 2.11 from master branch, we can add this method to the typeclass itself and have the syntax delegate to it. Would you make that change? |
no problem @kailuowang, I just pushed the change :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
The original implementation of the code to expose the `ConditionalCheckFailedException` was introduced with PR #212 in May 2018, but I'm not sure why the multi-line implementation was necessary - there's a discussion in PR #212, but I don't quite follow it: #212 (comment) The Cats `recover` functionality I'm using here was added with `ApplicativeError` in typelevel/cats#812 in January 2016, so it would have been available for PR #212. Perhaps it was some consequence of us being on AWS SDK v1 at that point, and having to use `AsyncHandler`? This implementation is definitely much more similar to ones we've used elsewhere, ie `ScalaFutureAdapter` and `PekkoInterpreter`. If we had a `ClassTag` we could go even smaller and use `attemptNarrow`, which was added to Cats with typelevel/cats#2863 in May 2019 - but even without that, the implementation is much smaller.
Hello, I already copy-pasted this function in a few places in my codebases, so I thought it could be useful to have it in cats.
Example use case (assuming
F : ApplicativeError[F, Throwable]
):