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.
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. |
rossabaker
left a comment
There was a problem hiding this comment.
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
uniteandseparatemethods don't need aMonadactually to do their job, because they only useflatMapin addition to methods fromAlternative. Therefore theFlatMap[F]constraint is just enough there.AlternativeandMonadimplementApplicative. That means theApplicativemethods can come by two different paths which creates sort of a loophole for ambiguity:Discussion
In fact, if it is okay to constraint the
uniteandseparatemethods with aMonad, then theAlternativetypeclass 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
Monadditivefor the sake of this example) which would inherit toMonadandMonoidK(viaAlternative) instead of justApplicativeandMonoidK(which the currentAlternativeinherits to). In this case the definition of those two methods –uniteandseparate– 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
Monadinstances, not onlyApplicative.