diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index b2432c0cd5c..45ce3d9620f 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -966,9 +966,13 @@ abstract private[data] class EitherTInstances extends EitherTInstances1 { Contravariant[Show].contramap(sh)(_.value) implicit def catsDataBifunctorForEitherT[F[_]](implicit F: Functor[F]): Bifunctor[EitherT[F, *, *]] = - new EitherTBifunctor[F] { - val F0: Functor[F] = F - } + new EitherTBifunctor[F] { val F0 = F } + + implicit def catsDataBifoldableForEitherT[F[_]](implicit F: Foldable[F]): Bifoldable[EitherT[F, *, *]] = + new EitherTBifoldable[F] { val F0 = F } + + implicit def catsDataBitraverseForEitherT[F[_]](implicit F: Traverse[F]): Bitraverse[EitherT[F, *, *]] = + new EitherTBitraverse[F] { val F0 = F } implicit def catsDataTraverseForEitherT[F[_], L](implicit FF: Traverse[F]): Traverse[EitherT[F, L, *]] = new EitherTTraverse[F, L] with EitherTFunctor[F, L] { @@ -1093,11 +1097,6 @@ abstract private[data] class EitherTInstances1 extends EitherTInstances2 { val F0: PartialOrder[F[Either[L, R]]] = F } - implicit def catsDataBitraverseForEitherT[F[_]](implicit F: Traverse[F]): Bitraverse[EitherT[F, *, *]] = - new EitherTBitraverse[F] with EitherTBifunctor[F] { - val F0: Traverse[F] = F - } - implicit def catsDataMonadErrorForEitherT[F[_], L](implicit F0: Monad[F]): MonadError[EitherT[F, L, *], L] = new EitherTMonadError[F, L] { implicit val F = F0 diff --git a/tests/shared/src/test/scala/cats/tests/EitherTSuite.scala b/tests/shared/src/test/scala/cats/tests/EitherTSuite.scala index c2276bdb2be..564c26721e4 100644 --- a/tests/shared/src/test/scala/cats/tests/EitherTSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/EitherTSuite.scala @@ -38,6 +38,12 @@ class EitherTSuite extends CatsSuite { implicit val iso: Isomorphisms[EitherT[ListWrapper, String, *]] = Isomorphisms .invariant[EitherT[ListWrapper, String, *]](EitherT.catsDataFunctorForEitherT(ListWrapper.functor)) + // Test instance summoning + def summon[F[_]: Traverse](): Unit = { + Bifunctor[EitherT[F, *, *]] + Bifoldable[EitherT[F, *, *]] + } + checkAll("EitherT[Eval, String, *]", DeferTests[EitherT[Eval, String, *]].defer[Int]) { @@ -74,6 +80,20 @@ class EitherTSuite extends CatsSuite { ) } + { + // if a Foldable for F is defined + implicit val F: Foldable[ListWrapper] = ListWrapper.foldable + + checkAll("EitherT[ListWrapper, Int, *]", FoldableTests[EitherT[ListWrapper, Int, *]].foldable[Int, Int]) + checkAll("Foldable[EitherT[ListWrapper, Int, *]]", + SerializableTests.serializable(Foldable[EitherT[ListWrapper, Int, *]]) + ) + checkAll("EitherT[ListWrapper, *, *]", BifoldableTests[EitherT[ListWrapper, *, *]].bifoldable[Int, Int, Int]) + checkAll("Bifoldable[EitherT[ListWrapper, *, *]]", + SerializableTests.serializable(Bifoldable[EitherT[ListWrapper, *, *]]) + ) + } + { // if a Traverse for F is defined implicit val F: Traverse[ListWrapper] = ListWrapper.traverse @@ -90,7 +110,6 @@ class EitherTSuite extends CatsSuite { checkAll("Bitraverse[EitherT[ListWrapper, *, *]]", SerializableTests.serializable(Bitraverse[EitherT[ListWrapper, *, *]]) ) - } {