-
-
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
move instances into separate trait #1659
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1659 +/- ##
==========================================
- Coverage 93.96% 93.95% -0.01%
==========================================
Files 241 246 +5
Lines 4091 4087 -4
Branches 160 157 -3
==========================================
- Hits 3844 3840 -4
Misses 247 247
Continue to review full report at Codecov.
|
@yilinwei thanks! I think that you raise a good point about While |
I like |
I forgot about the piecemeal imports; I think we should definitely include them. I also agree with @edmundnoble that they should sit under |
Thanks for adding the piecemeal imports @yilinwei. This looks good to me. It's a little bit of a head-scratcher to think about the fact that codecov is legitimately reporting a slight code coverage drop on this PR. While it's pretty trivial, it may be good to hit the new piecemeal imports in unit tests to make sure that they work as intended. I also think that it would be good to have the unit tests check some implicit resolutions for things like the |
@ceedubs I feel those tests ought to be autogenerated, ideally something along the lines of,
should reify into wdyt? |
I've committed an example of what I mean; The macro generates an There are two problems at the moment though;
|
I like the idea of testing the resolution of all the type class instances in the hierarchy. |
I've simplified the macro to just do the The names are I still need to deal with project structures, but the scalac flag problem should go away. @peterneyens I've added an example for the |
My original concern is that we might have incentive to go the other direction, i.e. move these instance into the companion objects for maintainability of binary compatibility. #1683 |
@kailuowang Sure; I was more hoping for feedback on whether people like this approach before taking it any further. Regardless I'll separate the changes from the original ones tomorrow with the additional tests suggested by @ceedubs. |
👍 from me. So this is good for merge once @yilinwei is finished with it. |
👍 modular build green |
class EqTests extends FunSuite { | ||
{ | ||
import cats.implicits._ | ||
implicitly[Invariant[Eq]] |
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.
Just nitpicking, but we don't need implicitly
in all these tests as simulacrum generates an apply
in the companion object. Should we just write Invariant[Eq]
, Invariant[Monoid]
, ...?
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.
changed
val empty = f(fa.empty) | ||
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) | ||
override def combineAll(bs: TraversableOnce[B]): B = | ||
f(fa.combineAll(bs.map(g))) |
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.
This line was not covered in the original code, which is a bit surprising to me. We can probably address it in a different PR. Just want to keep a note here.
def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] = new Semigroup[B] { | ||
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) | ||
override def combineAllOption(bs: TraversableOnce[B]): Option[B] = | ||
fa.combineAllOption(bs.map(g)).map(f) |
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.
This line was not covered in the original code, which is a bit surprising to me. We can probably address it in a different PR. Just want to keep a note here.
def pure[A](a: A): Semigroup[A] = new Semigroup[A] { | ||
def combine(x: A, y: A): A = a | ||
override def combineAllOption(as: TraversableOnce[A]): Option[A] = | ||
if (as.isEmpty) None else Some(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.
This line was not covered in the original code. We can probably address it in a different PR. Just want to keep a note here.
Merging with three thumbs up. Thanks @yilinwei! |
* cats.kernel.Hash and related instances (#1690) * Hash laws * all test passed * Hash instances for tuples * introduce implicit precedence in KernelBoiler: Order > PartialOrder > Eq; Hash > Eq. * Add type alias in cats._; Add contravariant instance for `Hash` * HashFunctions extends EqFunctions * Move contravariant instances to separate trait, in accordance with (#1659) * revert name change * move EitherInstances1#EitherEq out * Optimize hash computation on case classes without allocating a new object * fixing the problem in CI build: method catsKernelStdOrderForChar()cats.kernel.instances.CharOrder in trait cats.kernel.instances.CharInstances has a different result type in current version, where it is cats.kernel.Order rather than cats.kernel.instances.CharOrder * Full compliance with how Scala generates hash codes on case classes; +SetHash * Cartesian[Hash] * ContravariantCartesian[Hash] * ContravariantCartesian[Hash]; Hash.fromHashing * style issues * remove unused import * some test cases * some test cases * +test for Contravariant[Hash] * +test for Contravariant[Hash] * Add NEL/NEV one (#1707) `NonEmptyList.one` is analogous to `_.pure[NonEmptyList]`. Alternative for `NonEmptyList.of(x)` where you don't pay the price of the varargs, which isn't used. * move instances into separate trait (#1659) * move instances into separate trait * adding separate objects for piecemeal imports * Adding implicit resolution tests for piecemeal imports for hierarchy * Removing explicit implicitly and using apply method * cats.kernel.Hash and related instances (#1690) * Hash laws * all test passed * Hash instances for tuples * introduce implicit precedence in KernelBoiler: Order > PartialOrder > Eq; Hash > Eq. * Add type alias in cats._; Add contravariant instance for `Hash` * HashFunctions extends EqFunctions * Move contravariant instances to separate trait, in accordance with (#1659) * revert name change * move EitherInstances1#EitherEq out * Optimize hash computation on case classes without allocating a new object * fixing the problem in CI build: method catsKernelStdOrderForChar()cats.kernel.instances.CharOrder in trait cats.kernel.instances.CharInstances has a different result type in current version, where it is cats.kernel.Order rather than cats.kernel.instances.CharOrder * Full compliance with how Scala generates hash codes on case classes; +SetHash * Cartesian[Hash] * ContravariantCartesian[Hash] * ContravariantCartesian[Hash]; Hash.fromHashing * style issues * remove unused import * some test cases * some test cases * +test for Contravariant[Hash] * +test for Contravariant[Hash] * cats.kernel.Hash and related instances (#1690) * Hash laws * all test passed * Hash instances for tuples * introduce implicit precedence in KernelBoiler: Order > PartialOrder > Eq; Hash > Eq. * Add type alias in cats._; Add contravariant instance for `Hash` * HashFunctions extends EqFunctions * Move contravariant instances to separate trait, in accordance with (#1659) * revert name change * move EitherInstances1#EitherEq out * Optimize hash computation on case classes without allocating a new object * fixing the problem in CI build: method catsKernelStdOrderForChar()cats.kernel.instances.CharOrder in trait cats.kernel.instances.CharInstances has a different result type in current version, where it is cats.kernel.Order rather than cats.kernel.instances.CharOrder * Full compliance with how Scala generates hash codes on case classes; +SetHash * Cartesian[Hash] * ContravariantCartesian[Hash] * ContravariantCartesian[Hash]; Hash.fromHashing * style issues * remove unused import * some test cases * some test cases * +test for Contravariant[Hash] * +test for Contravariant[Hash] * Fix duplication error and style error * fix merge error * remove instance for Cartesian[Hash]: it does not satisfy associativity * +identityHash, +`hash` postfix method * all tests passed * increase coverage * accidentally removed plugin, restore it * all tests passed * increase coverage * increase coverage, ## => hashCode, kernelBoiler * suppress mimaReportBinaryIssues * Remove cats.functor * Remove cats.functor
#1657
The current instances sit in the object of
Contravariant
.This means that you can't get an implicit of a subclass -
implicitly[Invariant[Order]]
doesn't work because the instance is not in the companion object ofOrder
orInvariant
and the methods such asimap
won't work either.I would argue that for the behaviour to be consistent with the other instances, these should be moved into separate traits.
Doing a quick grep for
Kernel...Instances
are affected.