Skip to content

Commit

Permalink
Merge pull request #4434 from armanbilge/topic/functor-compose-bifunctor
Browse files Browse the repository at this point in the history
Add `Functor#composeBifunctor`
  • Loading branch information
armanbilge authored May 7, 2023
2 parents d7b2288 + 3b50e1e commit d5f7d63
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 5 deletions.
5 changes: 0 additions & 5 deletions core/src/main/scala/cats/Bifunctor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,6 @@ object Bifunctor extends cats.instances.NTupleBifunctorInstances {
@deprecated("Use cats.syntax object imports", "2.2.0")
object nonInheritedOps extends ToBifunctorOps

implicit def bifunctorInFunctorInstance[F[_]: Functor, G[_, _]: Bifunctor]: Bifunctor[λ[(A, B) => F[G[A, B]]]] =
new Bifunctor[λ[(A, B) => F[G[A, B]]]] {
override def bimap[W, X, Y, Z](fab: F[G[W, X]])(f: W => Y, g: X => Z): F[G[Y, Z]] =
Functor[F].map(fab)(Bifunctor[G].bimap(_)(f, g))
}
}

private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] extends Bifunctor[λ[(A, B) => F[G[A, B], G[A, B]]]] {
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/Composed.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ private[cats] trait ComposedFunctor[F[_], G[_]] extends Functor[λ[α => F[G[α]
F.map(fga)(ga => G.map(ga)(f))
}

private[cats] trait ComposedFunctorBifunctor[F[_], G[_, _]] extends Bifunctor[λ[(α, β) => F[G[α, β]]]] { outer =>
def F: Functor[F]
def G: Bifunctor[G]

def bimap[W, X, Y, Z](fab: F[G[W, X]])(f: W => Y, g: X => Z): F[G[Y, Z]] =
F.map(fab)(G.bimap(_)(f, g))
}

private[cats] trait ComposedApply[F[_], G[_]] extends Apply[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { outer =>
def F: Apply[F]
def G: Apply[G]
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/scala/cats/Functor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ trait Functor[F[_]] extends Invariant[F] { self =>
val G = Functor[G]
}

def composeBifunctor[G[_, _]: Bifunctor]: Bifunctor[λ[(α, β) => F[G[α, β]]]] =
new ComposedFunctorBifunctor[F, G] {
val F = self
val G = Bifunctor[G]
}

override def composeContravariant[G[_]: Contravariant]: Contravariant[λ[α => F[G[α]]]] =
new ComposedCovariantContravariant[F, G] {
val F = self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class BifunctorSuite extends CatsSuite {

{
type Tuple2InsideOption[A, B] = Option[(A, B)]
implicit val composedBifunctor: Bifunctor[Tuple2InsideOption] = Functor[Option].composeBifunctor[(*, *)]
checkAll(
"Bifunctor[Option[(A, B)]",
BifunctorTests[Tuple2InsideOption].bifunctor[String, String, String, Int, Int, Int]
Expand Down

0 comments on commit d5f7d63

Please sign in to comment.