-
-
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 CommutativeApply and CommutativeApplicative #1927
Conversation
…mmutativeSemigroup, ?]
8c95312
to
0ea4ac0
Compare
Codecov Report
@@ Coverage Diff @@
## master #1927 +/- ##
==========================================
- Coverage 96.21% 96.13% -0.09%
==========================================
Files 272 278 +6
Lines 4628 4655 +27
Branches 124 130 +6
==========================================
+ Hits 4453 4475 +22
- Misses 175 180 +5
Continue to review full report at Codecov.
|
* | ||
* Must obey the laws defined in cats.laws.CommutativeApplicativeLaws. | ||
*/ | ||
@typeclass trait CommutativeApplicative[F[_]] extends Applicative[F] with CommutativeApply[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.
For some reason Codecov doesn't think this is being hit, does anyone know why?
This seems like a very interesting property (one that Option springs to mind as a canonical example), but chat can I do with an instance? Can we not write a method or two to show the value of the abstraction. I tend to think to make it into cats an abstraction needs to pay its way. I haven’t yet seen that here, but probably because I am unfamiliar. |
You could use this property to properly constrain general rewrite systems like monadless (which preserves equational reasoning only for commutative monads). None of these observations leads us closer to an easy example though. @edmundnoble mentioned that it might be handy for optimizing free applicatives since you could re-order effects. |
@johnynek Given the ability to reorder computations in FreeApplicative, you can batch them safely. Also, unordered containers can be traversed safely with |
those are good examples. Could we add the methods to this PR? |
Hmm, so as I see we could either create some sort of Leaning towards the former, as the latter might open another larger can of worms (Would a On another note, once #1837 is merged, I'm pretty sure all the |
ef2c94b
to
edd6ba8
Compare
edd6ba8
to
0cd4eb9
Compare
Okay, maybe |
This reverts commit 0cd4eb9.
@LukaJCB What was the issue with |
Yeah, but only if the result is successful:
|
@LukaJCB hell. Can't ever win with |
You really can't 😄. Want to weigh in on syntax sugar vs type class? :) |
6c2a240
to
fcb429d
Compare
Another cool thing is that |
fcb429d
to
5bf6f35
Compare
5bf6f35
to
d3a803a
Compare
implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant]: Invariant[Nested[F, G, ?]] = | ||
new NestedInvariant[F, G] { | ||
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeContravariant[G] | ||
} | ||
} | ||
|
||
private[data] sealed abstract class NestedInstances11 extends NestedInstances12 { | ||
implicit def catsDataCommutativeApplyForNestedContravariant[F[_]: CommutativeApply, G[_]: CommutativeApply]: CommutativeApply[Nested[F, 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.
Usually we place more specific instance higher priority, i.e. CommutativeApply
and CommutativeApplicative
should have higher priority than Apply
and Applicative
.
CommutativeApplicative
should have higher priority than CommutativeApply
.
Also line 53 the instance name was wrong catsDataContravariantForNested
-> catsDataFunctorForNested
do you mind fix that in this PR as well?
* | ||
* Must obey the laws defined in cats.laws.CommutativeApplicativeLaws. | ||
*/ | ||
@typeclass trait CommutativeApplicative[F[_]] extends Applicative[F] with CommutativeApply[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.
I wonder if we really want an UnorderedFoldable
and UnorderedTraverse
that instead of toList
has toSet
and has a foldMap
that takes a CommutativeMonoid
and for sequence/traverse
uses CommutativeApplicative
.
That seems cleaner to me than putting these methods here now that I think about it.
I think we can construct sane laws for UnorderedFoldable
that would make sense. If we added a method like insert[T](f: F[T], item: T): F[T]
then I think you could make some law.
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 agree that an extra type class would feel a lot cleaner than baking these 4 operations into the CommutativeApplicative
type class. Related thoughts here.
I've played around with some laws, and we wouldn't have to get rid of too many laws too make it fit. I also like the insert
, although I'd have to think about it more. We could let Foldable
extend UnorderedFoldable
, if that makes any sense. I'll play around with it and update the PR accordingly :)
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 opens up a can of worms though. We could probably also define something like unorderedFoldM
with CommutativeMonad
, a UnorderedReducible
, NonEmptyUnordered
and all kinds of others. I came up with something crazy a while ago on gitter https://gitter.im/typelevel/cats-dev?at=59cf81a5210ac269208e0bcf but seems I've only scratched the surface 😄
I'll try to define this as minimal as possible and go from there. Might make a good blog post though.
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 had to remove insert
for now, because it's not possible to implement it for Map
:/
d3f10ca
to
d308cf7
Compare
I have a proposal: |
Yeah I can do that :) |
4889a52
to
e0069a8
Compare
…l functions there" This reverts commit d308cf7.
908c914
to
305d740
Compare
@@ -15,6 +16,28 @@ class MapSuite extends CatsSuite { | |||
checkAll("Map[Int, Int] with Option", TraverseTests[Map[Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) | |||
checkAll("Traverse[Map[Int, ?]]", SerializableTests.serializable(Traverse[Map[Int, ?]])) | |||
|
|||
test("traverseUnordered identity") { |
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.
you forgot to remove these tests
305d740
to
028b9a7
Compare
This reverts commit 0ffbc55.
028b9a7
to
d673655
Compare
Moved the unordered stuff to #1981 |
thanks so much! @LukaJCB |
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 @LukaJCB !
Had a quick discussion about this on gitter. Also adds an instance for
Validated[E: CommutativeSemigroup, ?]
:)