-
-
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 InvariantSemigroupal and ability to turn Monoidals to Monoids #2088
Changes from 23 commits
ec1f604
2edcb85
495cc74
d8b496d
19dc0ff
38b46e6
f4b7490
f9df1c3
5e17eed
8e2f7ab
3bfaf86
b7f36f2
94b0d2e
5443046
1a10366
dfbcf66
7880ada
3e3982f
95f58ff
4b73af8
30391e8
18f353d
436e444
ff0a355
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,7 +125,7 @@ private[cats] trait ComposedApplicativeContravariantMonoidal[F[_], G[_]] extends | |
def F: Applicative[F] | ||
def G: ContravariantMonoidal[G] | ||
|
||
override def unit[A]: F[G[A]] = F.pure(G.unit) | ||
override def unit: F[G[Unit]] = F.pure(G.unit) | ||
|
||
override def contramap[A, B](fa: F[G[A]])(f: B => A): F[G[B]] = | ||
F.map(fa)(G.contramap(_)(f)) | ||
|
@@ -144,6 +144,18 @@ private[cats] trait ComposedSemigroupal[F[_], G[_]] extends ContravariantSemigro | |
} | ||
} | ||
|
||
private[cats] trait ComposedInvariantApplySemigroupal[F[_], G[_]] extends InvariantSemigroupal[λ[α => F[G[α]]]] with ComposedInvariantCovariant[F, G] { outer => | ||
def F: InvariantSemigroupal[F] | ||
def G: Apply[G] | ||
|
||
def product[A, B](fa: F[G[A]], fb: F[G[B]]): F[G[(A, B)]] = | ||
F.imap(F.product(fa, fb)) { case (ga, gb) => | ||
G.map2(ga, gb)(_ -> _) | ||
} { g: G[(A, B)] => | ||
(G.map(g)(_._1), G.map(g)(_._2)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is not tested, we might need to test an instance that is not a covariant. |
||
} | ||
} | ||
|
||
private[cats] trait ComposedCovariantContravariant[F[_], G[_]] extends Contravariant[λ[α => F[G[α]]]] { outer => | ||
def F: Functor[F] | ||
def G: Contravariant[G] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package cats | ||
|
||
import simulacrum.typeclass | ||
|
||
/** | ||
* [[InvariantSemigroupal]] is nothing more than something both invariant | ||
* and Semigroupal. It comes up enough to be useful, and composes well | ||
*/ | ||
@typeclass trait InvariantSemigroupal[F[_]] extends Semigroupal[F] with Invariant[F] { self => | ||
|
||
def composeApply[G[_]: Apply]: InvariantSemigroupal[λ[α => F[G[α]]]] = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any plan to test cover this one as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has this been addressed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep! |
||
new ComposedInvariantApplySemigroupal[F, G] { | ||
def F = self | ||
def G = Apply[G] | ||
} | ||
|
||
} | ||
|
||
object InvariantSemigroupal extends SemigroupalArityFunctions { | ||
/** | ||
* Gives a `Semigroup` instance if A itself has a `Semigroup` instance. | ||
*/ | ||
def semigroup[F[_], A](implicit F: InvariantSemigroupal[F], A: Semigroup[A]): Semigroup[F[A]] = | ||
new InvariantSemigroupalSemigroup[F, A](F, A) | ||
} | ||
|
||
private[cats] class InvariantSemigroupalSemigroup[F[_], A](f: InvariantSemigroupal[F], sg: Semigroup[A]) extends Semigroup[F[A]] { | ||
def combine(a: F[A], b: F[A]): F[A] = | ||
InvariantSemigroupal.imap2(a, b)(sg.combine)(a => (a, a))(f, f) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -247,10 +247,6 @@ private[data] sealed abstract class IndexedStateTInstances extends IndexedStateT | |
implicit def catsDataAlternativeForIndexedStateT[F[_], S](implicit FM: Monad[F], | ||
FA: Alternative[F]): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] = | ||
new IndexedStateTAlternative[F, S] { implicit def F = FM; implicit def G = FA } | ||
|
||
implicit def catsDataContravariantMonoidalForIndexedStateT[F[_], S](implicit FD: ContravariantMonoidal[F], | ||
FA: Applicative[F]): ContravariantMonoidal[IndexedStateT[F, S, S, ?]] = | ||
new IndexedStateTContravariantMonoidal[F, S] { implicit def F = FD; implicit def G = FA } | ||
} | ||
|
||
private[data] sealed abstract class IndexedStateTInstances1 extends IndexedStateTInstances2 { | ||
|
@@ -387,11 +383,11 @@ private[data] sealed abstract class IndexedStateTContravariantMonoidal[F[_], S] | |
implicit def F: ContravariantMonoidal[F] | ||
implicit def G: Applicative[F] | ||
|
||
override def unit[A]: IndexedStateT[F, S, S, A] = | ||
IndexedStateT.applyF(G.pure((s: S) => F.unit[(S, A)])) | ||
override def unit: IndexedStateT[F, S, S, Unit] = | ||
IndexedStateT.applyF(G.pure((s: S) => F.trivial[(S, Unit)])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's reported that this instance is not tested. Shall we add one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I incline to remove this instance, WDYT @stephen-lazaro ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, it seems at best awkward and unuseful. |
||
|
||
override def contramap[A, B](fa: IndexedStateT[F, S, S, A])(f: B => A): IndexedStateT[F, S, S, B] = | ||
contramap2(fa, unit)(((a: A) => (a, a)) compose f) | ||
contramap2(fa, trivial)(((a: A) => (a, a)) compose f) | ||
|
||
override def product[A, B](fa: IndexedStateT[F, S, S, A], fb: IndexedStateT[F, S, S, B]): IndexedStateT[F, S, S, (A, B)] = | ||
contramap2(fa, fb)(identity) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ trait EqInstances { | |
* Defaults to the trivial equivalence relation | ||
* contracting the type to a point | ||
*/ | ||
def unit[A]: Eq[A] = Eq.allEqual | ||
def unit: Eq[Unit] = Eq.allEqual | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not quite sure I understand why this one is reported as not tested either. Any idea? |
||
|
||
/** Derive an `Eq` for `B` given an `Eq[A]` and a function `B => 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.
do you plan to add tests for this instance?