-
-
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
[Do not merge] Separate Bitraverse hierarchy default implementations #1194
Conversation
This is a first-step for typelevel#992. I've started with the Bitraverse type hierarchy because it's not a very deep one. The idea is that we would continue this effort for other type class hierarchies.
Codecov Report
@@ Coverage Diff @@
## master #1194 +/- ##
==========================================
- Coverage 89.16% 89.09% -0.07%
==========================================
Files 234 234
Lines 3137 3164 +27
Branches 52 54 +2
==========================================
+ Hits 2797 2819 +22
- Misses 340 345 +5
Continue to review full report at Codecov.
|
Thanks for bringing this forward, @ceedubs! One aspect I don't like about this is that it clutters the |
@fthomas I like that. I'll give it a go. |
👍 thanks so much @ceedubs |
This is an attempt to not have net negative code coverage on typelevel#1194.
} | ||
|
||
private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] | ||
extends Bifunctor[λ[(A, B) => F[G[A, B], G[A, B]]]] { | ||
extends Bifunctor.Default[λ[(A, B) => F[G[A, B], G[A, B]]]] { |
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.
It seems I missed this in #1079, maybe you can change the type projection to λ[(α, β) => F[G[α, β], G[α, β]]]
in this PR ?
I don't think they are binary compatible because the traits may become interface only traits, and that might eliminate the classes that were hanging around to give the implementations. It sounds like there was already a discussion, but I'll add my thoughts for what they might be worth: I'm excited most about cats when we can use broadly agreed upon best practices for FP in scala (generally learned from a few years of lessons) coupled with well established and valuable abstractions. I'm less excited about more speculative stuff because often those don't work out like we hope, and we want to change it later, which results in churn. I hope cats can (very soon) have a high stability bar so that it is safe to put it as a library that libraries depend on. I'm personally not super excited about this. I certainly see that a careless implementer might not do the best thing, but I assume that careless person will just use the default types too. I'd rather not make this change to kernel. It seems like it mostly adds friction with the hope of nagging someone into thinking more. |
Let's hold off on merging this for now. I'm not sure I want to go forward with this if it's going to be a disconnect between |
@johnynek oh one more note:
Totally agreed. My (personal) goal is a 1.0 release candidate by the end of September. I wasn't sure whether or not there was any wiggle room for |
@johnynek I'll follow up with some of my thoughts here. I've tried to include some points on both sides of whether or not this should happen. Please feel free to weigh in with any others you may have. Just to put them into perspective, I'm really not set on this change being made. There seemed to be several people who wanted this at the Typelevel Summit in Philly and no real objections, so I've gone forward with it, but I'm okay with it not landing in Cats. Potential BenefitsLess ArbitraryWhich methods we choose to be abstract and which are derived is somewhat arbitrary in some cases. For example, I tend to think of Reminds you to OverrideI think @non's main goal for this was to be able to opt-in to getting compile errors if you forget to override a method. For example, the default In practice, I think it's fairly rare that you would want to do this, because it's going to result in a lot of boilerplate, and you are probably usually okay if you just remember to override a few common methods. There is one particular use-case in which I have wanted this. I've wanted to create helpers for creating type class instances for isomorphic types. For example, if you have an Again, in practice this probably wouldn't be that bad as long as you remembered to override several key methods. I think the lack of compiler help is unfortunate, but it's not the end of the world. Pure InterfaceThis results in interface-only traits. This could potentially be helpful for people who want to use Cats from Java, but I don't think we've ever had that goal in mind, so I don't really put any weight on this. Potential DownsidesCompatibilityThis is currently not how Cats is set up (including IndirectionIt's another layer of indirection for users. Now they not only need to know what a I think this downside can largely be counteracted by a little bit of effort in the documentation, but it's still there. Rare use-casesI think that even within the Cats source itself we will probably end up using the |
@non what are your thoughts on this? I know when we met up a while back we had mentioned this being something we wanted in 1.0. |
While I was working on One advantage is that we can reuse them to write consistency laws. |
@julien-truffaut that looks like a pretty good idea to me. Though there is still the question of whether the default implementations should exist in the type class trait itself. It sounds like @johnynek votes no. I think that I could be convinced either way. @typelevel/cats does anyone have strong opinions on this? It's a big decision item that needs to be resolved before 1.0. |
This was originally part of typelevel#1194, but since it's looking uncertain whether or not that will go forward, I'm separating it to here.
@ceedubs Do you plan to include default implementations in 1.0, or would this PR be better off closed for now? |
Closing stale PRs. Feel free to reopen if there is interest to revive the effort. |
This is a first-step for #992. I've started with the Bitraverse type
hierarchy because it's not a very deep one. The idea is that we would
continue this effort for other type class hierarchies.
I am not particularly fond of the
DefaultX
naming convention, but it was the least bad of the ones I could think of. I'm open to other ideas.