Skip to content
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

Extend Functor implementation in the Traverse instance of EitherT, OptionT and Tuple2K #2191

Merged
merged 6 commits into from
May 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions core/src/main/scala/cats/data/EitherK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private[data] sealed abstract class EitherKInstances2 extends EitherKInstances3

private[data] sealed abstract class EitherKInstances1 extends EitherKInstances2 {
implicit def catsDataCoflatMapForEitherK[F[_], G[_]](implicit F0: CoflatMap[F], G0: CoflatMap[G]): CoflatMap[EitherK[F, G, ?]] =
new EitherKCoflatMap[F, G] {
new EitherKCoflatMap[F, G] with EitherKFunctor[F, G] {
implicit def F: CoflatMap[F] = F0

implicit def G: CoflatMap[G] = G0
Expand All @@ -149,7 +149,7 @@ private[data] sealed abstract class EitherKInstances1 extends EitherKInstances2

private[data] sealed abstract class EitherKInstances0 extends EitherKInstances1 {
implicit def catsDataTraverseForEitherK[F[_], G[_]](implicit F0: Traverse[F], G0: Traverse[G]): Traverse[EitherK[F, G, ?]] =
new EitherKTraverse[F, G] {
new EitherKTraverse[F, G] with EitherKFunctor[F, G] {
implicit def F: Traverse[F] = F0

implicit def G: Traverse[G] = G0
Expand All @@ -159,7 +159,7 @@ private[data] sealed abstract class EitherKInstances0 extends EitherKInstances1
private[data] sealed abstract class EitherKInstances extends EitherKInstances0 {

implicit def catsDataComonadForEitherK[F[_], G[_]](implicit F0: Comonad[F], G0: Comonad[G]): Comonad[EitherK[F, G, ?]] =
new EitherKComonad[F, G] {
new EitherKComonad[F, G] with EitherKFunctor[F, G] {
implicit def F: Comonad[F] = F0

implicit def G: Comonad[G] = G0
Expand All @@ -171,7 +171,7 @@ private[data] trait EitherKFunctor[F[_], G[_]] extends Functor[EitherK[F, G, ?]]

implicit def G: Functor[G]

def map[A, B](a: EitherK[F, G, A])(f: A => B): EitherK[F, G, B] =
override def map[A, B](a: EitherK[F, G, A])(f: A => B): EitherK[F, G, B] =
a map f
}

Expand Down
19 changes: 13 additions & 6 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -462,13 +462,14 @@ private[data] abstract class EitherTInstances extends EitherTInstances1 {
Contravariant[Show].contramap(sh)(_.value)

implicit def catsDataBifunctorForEitherT[F[_]](implicit F: Functor[F]): Bifunctor[EitherT[F, ?, ?]] =
new Bifunctor[EitherT[F, ?, ?]] {
override def bimap[A, B, C, D](fab: EitherT[F, A, B])(f: A => C, g: B => D): EitherT[F, C, D] = fab.bimap(f, g)
new EitherTBifunctor[F] {
val F0: Functor[F] = F
}

implicit def catsDataTraverseForEitherT[F[_], L](implicit F: Traverse[F]): Traverse[EitherT[F, L, ?]] =
new EitherTTraverse[F, L] {
val F0: Traverse[F] = F
implicit def catsDataTraverseForEitherT[F[_], L](implicit FF: Traverse[F]): Traverse[EitherT[F, L, ?]] =
new EitherTTraverse[F, L] with EitherTFunctor[F, L] {
val F0: Traverse[F] = FF
val F: Functor[F] = FF
}

implicit def catsMonoidForEitherT[F[_], L, A](implicit F: Monoid[F[Either[L, A]]]): Monoid[EitherT[F, L, A]] =
Expand All @@ -492,7 +493,7 @@ private[data] abstract class EitherTInstances1 extends EitherTInstances2 {
}

implicit def catsDataBitraverseForEitherT[F[_]](implicit F: Traverse[F]): Bitraverse[EitherT[F, ?, ?]] =
new EitherTBitraverse[F] {
new EitherTBitraverse[F] with EitherTBifunctor[F] {
val F0: Traverse[F] = F
}

Expand Down Expand Up @@ -640,6 +641,12 @@ private[data] sealed trait EitherTBitraverse[F[_]] extends Bitraverse[EitherT[F,
fab.bitraverse(f, g)
}

private[data] sealed trait EitherTBifunctor[F[_]] extends Bifunctor[EitherT[F, ?, ?]] {
implicit def F0: Functor[F]

override def bimap[A, B, C, D](fab: EitherT[F, A, B])(f: A => C, g: B => D): EitherT[F, C, D] = fab.bimap(f, g)
}

private[data] sealed trait EitherTEq[F[_], L, A] extends Eq[EitherT[F, L, A]] {
implicit def F0: Eq[F[Either[L, A]]]

Expand Down
41 changes: 19 additions & 22 deletions core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,24 @@ private[data] sealed abstract class RWSTMonad[F[_], E, L, S] extends IRWSTFuncto
}
}

private[data] sealed abstract class IRWSTSemigroupK[F[_], E, L, SA, SB] extends SemigroupK[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] {
private[data] sealed abstract class IRWSTSemigroupK[F[_], E, L, SA, SB] extends IRWSTSemigroupK1[F, E, L, SA, SB]

private[data] sealed abstract class RWSTAlternative[F[_], E, L, S] extends IRWSTFunctor[F, E, L, S, S] with RWSTAlternative1[F, E, L, S]

private[data] sealed abstract class RWSTMonadError[F[_], E, L, S, R]
extends RWSTMonad[F, E, L, S] with MonadError[ReaderWriterStateT[F, E, L, S, ?], R] {

implicit def F: MonadError[F, R]

def raiseError[A](r: R): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.liftF(F.raiseError(r))

def handleErrorWith[A](fa: ReaderWriterStateT[F, E, L, S, A])(f: R => ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] =
ReaderWriterStateT { (e, s) =>
F.handleErrorWith(fa.run(e, s))(r => f(r).run(e, s))
}
}

private trait IRWSTSemigroupK1[F[_], E, L, SA, SB] extends SemigroupK[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] {
implicit def F: Monad[F]
implicit def G: SemigroupK[F]

Expand All @@ -574,19 +591,12 @@ private[data] sealed abstract class IRWSTSemigroupK[F[_], E, L, SA, SB] extends
}
}

private[data] sealed abstract class RWSTAlternative[F[_], E, L, S]
extends IRWSTFunctor[F, E, L, S, S] with Alternative[ReaderWriterStateT[F, E, L, S, ?]] {
private trait RWSTAlternative1[F[_], E, L, S] extends IRWSTSemigroupK1[F, E, L, S, S] with Alternative[ReaderWriterStateT[F, E, L, S, ?]] {

implicit def F: Monad[F]
def G: Alternative[F]
implicit def L: Monoid[L]

def combineK[A](x: ReaderWriterStateT[F, E, L, S, A],
y: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] =
ReaderWriterStateT { (e, sa) =>
G.combineK(x.run(e, sa), y.run(e, sa))
}

def empty[A]: ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.liftF(G.empty[A])

def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.pure[F, E, L, S, A](a)
Expand All @@ -595,16 +605,3 @@ private[data] sealed abstract class RWSTAlternative[F[_], E, L, S]
ff.flatMap(f => fa.map(f)(F))(F, L)

}

private[data] sealed abstract class RWSTMonadError[F[_], E, L, S, R]
extends RWSTMonad[F, E, L, S] with MonadError[ReaderWriterStateT[F, E, L, S, ?], R] {

implicit def F: MonadError[F, R]

def raiseError[A](r: R): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.liftF(F.raiseError(r))

def handleErrorWith[A](fa: ReaderWriterStateT[F, E, L, S, A])(f: R => ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] =
ReaderWriterStateT { (e, s) =>
F.handleErrorWith(fa.run(e, s))(r => f(r).run(e, s))
}
}
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/IorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ private[data] abstract class IorTInstances extends IorTInstances1 {
}

implicit def catsDataTraverseForIorT[F[_], A](implicit F: Traverse[F]): Traverse[IorT[F, A, ?]] =
new IorTTraverse[F, A] { val F0: Traverse[F] = F }
new IorTTraverse[F, A] with IorTFunctor[F, A] { val F0: Traverse[F] = F }

implicit def catsDataMonoidForIorT[F[_], A, B](implicit F: Monoid[F[Ior[A, B]]]): Monoid[IorT[F, A, B]] =
new IorTMonoid[F, A, B] { val F0: Monoid[F[Ior[A, B]]] = F }
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private[data] sealed abstract class KleisliInstances6 extends KleisliInstances7

private[data] sealed abstract class KleisliInstances7 extends KleisliInstances8 {
implicit def catsDataDistributiveForKleisli[F[_], R](implicit F0: Distributive[F]): Distributive[Kleisli[F, R, ?]] =
new KleisliDistributive[F, R] { implicit def F: Distributive[F] = F0 }
new KleisliDistributive[F, R] with KleisliFunctor[F, R] { implicit def F: Distributive[F] = F0 }
}

private[data] sealed abstract class KleisliInstances8 {
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/Nested.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private[data] sealed abstract class NestedInstances extends NestedInstances0 {
}

implicit def catsDataContravariantMonoidalForApplicativeForNested[F[_]: Applicative, G[_]: ContravariantMonoidal]: ContravariantMonoidal[Nested[F, G, ?]] =
new NestedContravariantMonoidal[F, G] {
new NestedContravariantMonoidal[F, G] with NestedContravariant[F, G] {
val FG: ContravariantMonoidal[λ[α => F[G[α]]]] = Applicative[F].composeContravariantMonoidal[G]
}
}
Expand Down Expand Up @@ -284,7 +284,7 @@ private[data] trait NestedNonEmptyTraverse[F[_], G[_]] extends NonEmptyTraverse[
private[data] trait NestedContravariant[F[_], G[_]] extends Contravariant[Nested[F, G, ?]] {
def FG: Contravariant[λ[α => F[G[α]]]]

def contramap[A, B](fga: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
override def contramap[A, B](fga: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
Nested(FG.contramap(fga.value)(f))
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ private[data] sealed abstract class OptionTInstances1 extends OptionTInstances2

private[data] sealed abstract class OptionTInstances2 extends OptionTInstances3 {
implicit def catsDataTraverseForOptionT[F[_]](implicit F0: Traverse[F]): Traverse[OptionT[F, ?]] =
new OptionTTraverse[F] { implicit val F = F0 }
new OptionTTraverse[F] with OptionTFunctor[F] { implicit val F = F0 }
}

private[data] sealed abstract class OptionTInstances3 {
Expand Down
31 changes: 19 additions & 12 deletions core/src/main/scala/cats/data/Tuple2K.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ private[data] sealed abstract class Tuple2KInstances extends Tuple2KInstances0 {
def G: Show[G[A]] = GF
}
implicit def catsDataContravariantMonoidalForTuple2k[F[_], G[_]](implicit FD: ContravariantMonoidal[F], GD: ContravariantMonoidal[G]): ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] =
new Tuple2KContravariantMonoidal[F, G] {
new Tuple2KContravariantMonoidal[F, G] with Tuple2KContravariant[F, G] {
def F: ContravariantMonoidal[F] = FD
def G: ContravariantMonoidal[G] = GD
}
}

private[data] sealed abstract class Tuple2KInstances0 extends Tuple2KInstances1 {
implicit def catsDataTraverseForTuple2K[F[_], G[_]](implicit FF: Traverse[F], GF: Traverse[G]): Traverse[λ[α => Tuple2K[F, G, α]]] = new Tuple2KTraverse[F, G] {
def F: Traverse[F] = FF
def G: Traverse[G] = GF
}
implicit def catsDataTraverseForTuple2K[F[_], G[_]](implicit FF: Traverse[F], GF: Traverse[G]): Traverse[λ[α => Tuple2K[F, G, α]]] =
new Tuple2KTraverse[F, G] with Tuple2KFunctor[F, G] {
def F: Traverse[F] = FF
def G: Traverse[G] = GF
}
implicit def catsDataContravariantForTuple2K[F[_], G[_]](implicit FC: Contravariant[F], GC: Contravariant[G]): Contravariant[λ[α => Tuple2K[F, G, α]]] = new Tuple2KContravariant[F, G] {
def F: Contravariant[F] = FC
def G: Contravariant[G] = GC
Expand Down Expand Up @@ -109,10 +110,11 @@ private[data] sealed abstract class Tuple2KInstances6 extends Tuple2KInstances7
}

private[data] sealed abstract class Tuple2KInstances7 extends Tuple2KInstances8 {
implicit def catsDataDistributiveForTuple2K[F[_], G[_]](implicit FF: Distributive[F], GG: Distributive[G]): Distributive[λ[α => Tuple2K[F, G, α]]] = new Tuple2KDistributive[F, G] {
def F: Distributive[F] = FF
def G: Distributive[G] = GG
}
implicit def catsDataDistributiveForTuple2K[F[_], G[_]](implicit FF: Distributive[F], GG: Distributive[G]): Distributive[λ[α => Tuple2K[F, G, α]]] =
new Tuple2KDistributive[F, G] with Tuple2KFunctor[F, G] {
def F: Distributive[F] = FF
def G: Distributive[G] = GG
}
}

private[data] sealed abstract class Tuple2KInstances8 {
Expand All @@ -132,14 +134,19 @@ private[data] sealed trait Tuple2KFunctor[F[_], G[_]] extends Functor[λ[α => T
private[data] sealed trait Tuple2KDistributive[F[_], G[_]] extends Distributive[λ[α => Tuple2K[F, G, α]]] {
def F: Distributive[F]
def G: Distributive[G]
override def distribute[H[_]: Functor, A, B](ha: H[A])(f: A => Tuple2K[F, G, B]): Tuple2K[F, G, H[B]] = Tuple2K(F.distribute(ha){a => f(a).first}, G.distribute(ha){a => f(a).second})
override def map[A, B](fa: Tuple2K[F, G, A])(f: A => B): Tuple2K[F, G, B] = Tuple2K(F.map(fa.first)(f), G.map(fa.second)(f))

override def distribute[H[_]: Functor, A, B](ha: H[A])(f: A => Tuple2K[F, G, B]): Tuple2K[F, G, H[B]] =
Tuple2K(F.distribute(ha){a => f(a).first}, G.distribute(ha){a => f(a).second})

override def map[A, B](fa: Tuple2K[F, G, A])(f: A => B): Tuple2K[F, G, B] =
Tuple2K(F.map(fa.first)(f), G.map(fa.second)(f))
}

private[data] sealed trait Tuple2KContravariant[F[_], G[_]] extends Contravariant[λ[α => Tuple2K[F, G, α]]] {
def F: Contravariant[F]
def G: Contravariant[G]
def contramap[A, B](fa: Tuple2K[F, G, A])(f: B => A): Tuple2K[F, G, B] = Tuple2K(F.contramap(fa.first)(f), G.contramap(fa.second)(f))
override def contramap[A, B](fa: Tuple2K[F, G, A])(f: B => A): Tuple2K[F, G, B] =
Tuple2K(F.contramap(fa.first)(f), G.contramap(fa.second)(f))
}

private[data] sealed trait Tuple2KContravariantMonoidal[F[_], G[_]] extends ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] {
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ private[data] sealed trait WriterTFunctor[F[_], L] extends Functor[WriterT[F, L,
private[data] sealed trait WriterTContravariant[F[_], L] extends Contravariant[WriterT[F, L, ?]] {
implicit def F0: Contravariant[F]

def contramap[A, B](fa: WriterT[F, L, A])(f: B => A): WriterT[F, L, B] =
override def contramap[A, B](fa: WriterT[F, L, A])(f: B => A): WriterT[F, L, B] =
fa.contramap(f)
}

Expand Down Expand Up @@ -420,7 +420,7 @@ private[data] sealed trait WriterTContravariantMonoidal[F[_], L] extends Contrav
override def unit: WriterT[F, L, Unit] = WriterT(F0.trivial[(L, Unit)])

override def contramap[A, B](fa: WriterT[F, L, A])(f: B => A): WriterT[F, L, B] =
WriterT(F0.contramap(fa.run)((d: (L, B)) => (d._1, f(d._2))))
fa.contramap(f)

override def product[A, B](fa: WriterT[F, L, A], fb: WriterT[F, L, B]): WriterT[F, L, (A, B)] =
WriterT(
Expand Down
4 changes: 3 additions & 1 deletion tests/src/test/scala/cats/tests/NestedSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ class NestedSuite extends CatsSuite {

{
// CommutativeApply composition
implicit val optionApply = Apply[Option]
implicit val validatedApply = Apply[Validated[Int, ?]]
checkAll("Nested[Option, Validated[Int, ?], ?]", CommutativeApplyTests[Nested[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int])
checkAll("CommutativeApply[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(CommutativeApply[Nested[Option, Validated[Int, ?], ?]]))
checkAll("CommutativeApply[Nested[Option, Validated[Int, ?], ?], ?]]", SerializableTests.serializable(CommutativeApply[Nested[Option, Validated[Int, ?], ?]]))
}

{
Expand Down
2 changes: 2 additions & 0 deletions tests/src/test/scala/cats/tests/Tuple2KSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Tuple2KSuite extends CatsSuite {
}

{
implicit val optionApply = Apply[Option]
implicit val validatedApply = Apply[Validated[Int, ?]]
checkAll("Tuple2K[Option, Validated[Int, ?], ?]", CommutativeApplyTests[Tuple2K[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int])
checkAll("Apply[Tuple2K[Option, Validated[Int, ?], ?]]", SerializableTests.serializable(CommutativeApply[Tuple2K[Option, Validated[Int, ?], ?]]))
}
Expand Down
2 changes: 0 additions & 2 deletions tests/src/test/scala/cats/tests/WriterTSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,6 @@ class WriterTSuite extends CatsSuite {

{
// F has a Comonad and L has a Monoid
implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int]
Comonad[(String, ?)]
Comonad[WriterT[(String, ?), ListWrapper[Int], ?]]

checkAll("WriterT[(String, ?), ListWrapper[Int], ?]", ComonadTests[WriterT[(String, ?), ListWrapper[Int], ?]].comonad[Int, Int, Int])
Expand Down