-
-
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
More instances for prod #1402
More instances for prod #1402
Conversation
Current coverage is 91.68% (diff: 100%)@@ master #1402 diff @@
==========================================
Files 240 240
Lines 3610 3632 +22
Methods 3546 3568 +22
Messages 0 0
Branches 63 63
==========================================
+ Hits 3310 3330 +20
- Misses 300 302 +2
Partials 0 0
|
Hi @adelbertc is there something else I can do here? |
checkAll("MonadCombine[Prod[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(MonadCombine[Prod[ListWrapper, ListWrapper, ?]])) | ||
} | ||
|
||
test("order") { |
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.
Can you check OrderLaws
as well? https://github.com/typelevel/cats/blob/master/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala
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.
Sure!
def F: Order[F[A]] = FF | ||
def G: Order[G[A]] = GF | ||
} | ||
implicit def catsDataShowForProd[F[_], G[_], A](implicit FF: Show[F[A]], GF: Show[G[A]]): Show[Prod[F, G, A]] = new ProdShow[F, G, 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 one can probably be moved up to ProdInstances
right
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.
Yes!
} | ||
|
||
private[data] sealed abstract class ProdInstances9 { | ||
implicit def catsDataOrderForProd[F[_], G[_], A](implicit FF: Order[F[A]], GF: Order[G[A]]): Order[Prod[F, G, A]] = new ProdOrder[F, G, 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 can probably be moved up to one sub class down from the Eq
instance
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.
Sure!
} | ||
|
||
private[data] sealed abstract class ProdInstances0 extends ProdInstances1 { | ||
implicit def catsDataMonoidKForProd[F[_], G[_]](implicit FF: MonoidK[F], GG: MonoidK[G]): MonoidK[λ[α => Prod[F, G, α]]] = new ProdMonoidK[F, G] { | ||
def F: MonoidK[F] = FF | ||
def G: MonoidK[G] = GG | ||
} | ||
|
||
implicit def catsDataOrderForProd[F[_], G[_], A](implicit FF: Order[F[A]], GF: Order[G[A]]): Order[Prod[F, G, A]] = new ProdOrder[F, G, 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.
As @adelbertc pointed out, Order
instance should have higher priority than Eq
since it's more specific. I think we should move this instance to ProdInstances
and the Eq
instance down here.
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.
Yes, sure! I misunderstood @adelbertc in the previous comment. Now it's done.
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 very much!
def G: MonadCombine[G] = GF | ||
} | ||
} | ||
|
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.
In this particular case, to ensure the more specific instance having the highest priority, we basically want to ensure that instances of typeclasses who are lower in the inheritance tree are also lower in the instance trait inheritance tree. For example, Monad
inherits Functor
and thus is more "specific" than Functor
, so it should be in an instance trait with higher priority (0 - 3) than where Functor
is (4).
So, we need to rearrange the instances to that order.
MonadCombine
<: Altenative
MonadCombine
<: Monad
<: Applicative
<: Apply
<: Functor
Traverse
<: Foldable
Traverse
<: Functor
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 for pointing that out, I didn't think on that!
I've done the changes in 000a583
def F: MonadCombine[F] = FF | ||
def G: MonadCombine[G] = GF | ||
private[data] sealed abstract class ProdInstances7 { | ||
implicit def catsDataAlternativeForProd[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[λ[α => Prod[F, G, α]]] = new ProdAlternative[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.
Thanks! We are getting close.
how about we do
ProdInstances
: MonadCombine
, Order
, Show
,Traverse
, Contravariant
ProdInstances0
: Alternative
, Monad
, Eq
, Foldable
ProdInstances1
: MonoidK
, Applicative
ProdInstances2
: SemigroupK
, Apply
ProdInstances3
: Functor
I might make some mistakes here too.
You may find this diagram helpful
https://camo.githubusercontent.com/28086d65ea5688b722ef4c19ee70e1974c5f4cb0/687474703a2f2f766972656f2e6f72672f746d702f74797065636c61737365732e737667
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! We are getting close.
how about we do
ProdInstances: MonadCombine, Order, Show ,Traverse, Contravariant
ProdInstances0: Alternative, Monad, Eq, Foldable
ProdInstances1: MonoidK, Applicative
ProdInstances2: SemigroupK, Apply
ProdInstances3: Functor
I might make some mistakes here too.
You may find this diagram helpful https://camo.githubusercontent.com/28086d65ea5688b722ef4c19ee70e1974c5f4cb0/687474703a2f2f766972656f2e6f72672f746d702f74797065636c61737365732e737667
Yep, I absolutely find that diagram helpful! Now that I can see at a glance what's the hierarchy between all typeclasses, your last structure seems correct! BTW, is this diagram accesible somewhere in the docs? |
@@ -46,20 +57,45 @@ private[data] sealed abstract class ProdInstances2 extends ProdInstances3 { | |||
} | |||
|
|||
private[data] sealed abstract class ProdInstances3 extends ProdInstances4 { | |||
implicit def catsDataMonadForProd[F[_], G[_]](implicit FM: Monad[F], GM: Monad[G]): Monad[λ[α => Prod[F, G, α]]] = new ProdMonad[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.
We can replace these λ[α => Prod[F, G, α]]
by just Prod[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.
Yep, sure!
But, what's the difference between the generated code of one and the other?
|
||
test("show") { | ||
forAll { (l1: Option[Int], l2: Option[Int]) => | ||
val showOptionInt = implicitly[Show[Option[Int]]] |
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.
Nitpicking, but this can just be val showOptionInt = Show[Option[Int]]
, right ?
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.
Yep, you're right :)
@kailuowang If I structure the code as you suggested:
I find ambiguous implicit values for
What do you think on the following structure? ProdInstances: MonadCombine, Order, Show, Contravariant The latter seems to work fine for me. |
@pepegar My bad, your suggestion looks fine to me. |
👍 on travis green |
LGTM 👍 |
Creating more instances for
Prod
:Monad
Foldable
Traverse
Order
MonadCombine
Show
fixes #1375