-
-
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
Relax a constraint for Alternative's unite and separate methods from Monad to FlatMap #3997
Relax a constraint for Alternative's unite and separate methods from Monad to FlatMap #3997
Conversation
Converting the PR to Draft since MiMa is not happy with it:
Let me investigate the issue first. If it is not worth the effort to fix it, I'll close the PR. |
If you keep the old one and make it There's also syntax to wrestle with. |
@rossabaker thank you for the advice. As I can see now it won't be an easy lift. Seems I managed to calm MiMa down at this point, although the solution I came up with looks quite ugly to me. As you can see in the last commit, I added a new
So I decided to try the opposite: place the new |
4a68a42
to
4bc84d7
Compare
ae92c24
to
25da570
Compare
25da570
to
834e720
Compare
Seems I managed to get through all the thorns with this task. The only caveat: Simulacrum Scalafix rules don't work correctly with all these binary compatibility tricks in |
def unite[G[_], A](fga: F[G[A]])(implicit FM: FlatMap[F], G: Foldable[G]): F[A] = | ||
FM.flatMap(fga) { G.foldMapK(_)(pure)(self) } |
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.
The original implementation is replaced with this better optimized one which utilizes Foldable.foldMapK
(instead of the former's foldLeft
).
cc @rossabaker, in case if you're curious in how I've fought it :) |
834e720
to
c9f8c17
Compare
c9f8c17
to
19f8982
Compare
Hmm.. Seems the build failure is not related to the PR:
I wonder – is the main branch broken (how come?) |
696864f
to
f22264e
Compare
Yes, that scala.js issue came up on another branch. Pretty sure it's a result of #4018. |
#4048 should fix the build. |
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.
Nice work! I've used package private to hide overloads, but can't recall ever using a protected. It seems to work. Have you tried calling it anywhere with something that has a FlatMap
but no Monad
? I'm mostly sure it will still work, but want to be 100% sure. (Maybe this encoding isn't as novel as I think.)
Right, good catch. First I tried to make it Interesting observation: this trick with |
Oh, so this is still going to fail MiMa even after #4048 is merged? 🤔 |
No, I don't think so. I mean, all the checks had been succeeding before #4018. But later I rebased this PR onto |
f22264e
to
51051ca
Compare
Good catch, thanks. Seems I overlooked that it has to be explicitly tested. Should be good now. |
51051ca
to
729cba9
Compare
@rossabaker thank you for keeping eye on this PR and helping me with polishing it, I appreciate it. Yeah, as you might notice, I eventually decided to revert access for |
5cd2beb
to
2f10dec
Compare
Ironically, this PR had got conflicts with another my PR that have been merged recently. |
The initial discussion is here.
Rationale
unite
andseparate
methods don't need aMonad
actually to do their job, because they only useflatMap
in addition to methods fromAlternative
. Therefore theFlatMap[F]
constraint is just enough there.Alternative
andMonad
implementApplicative
. That means theApplicative
methods can come by two different paths which creates sort of a loophole for ambiguity:Discussion
In fact, if it is okay to constraint the
unite
andseparate
methods with aMonad
, then theAlternative
typeclass is absolutely redundant in such a case – we can simply put these two methods directly intoMonoidK
.Another approach (perhaps even better one) could be a new typeclass (let's name it
Monadditive
for the sake of this example) which would inherit toMonad
andMonoidK
(viaAlternative
) instead of justApplicative
andMonoidK
(which the currentAlternative
inherits to). In this case the definition of those two methods –unite
andseparate
– could be simplified to the following:In other words, an additional constraint for
F[_]
is not necessary anymore.Therefore such a new typeclass would allow to reduce number of additional constraints passed to those methods.
And looks like it would make a lot of sense anyway – most of the containers which Cats supports implement corresponding
Monad
instances, not onlyApplicative
.