All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalaz.Tannen.scala Maven / Gradle / Ivy

The newest version!
package scalaz

/** Composes a Functor on the outside of a Bifunctor.
  *
  * [[https://hackage.haskell.org/package/bifunctors-5.5/docs/Data-Bifunctor-Tannen.html#t:Tannen]]
  */
final case class Tannen[F[_], G[_, _], A, B](f: F[G[A, B]])

object Tannen extends TannenInstances

sealed abstract class TannenInstances0 {
  implicit def TannenFoldable[F[_], G[_, _], E](implicit F: Foldable[F], G: Bifoldable[G]): Foldable[Tannen[F, G, E, *]] =
    new Foldable[Tannen[F, G, E, *]] {
      def foldMap[A, M](fa: Tannen[F, G, E, A])(f: A => M)(implicit M: Monoid[M]): M =
        F.foldMap(fa.f)(G.bifoldMap(_)(_ => M.zero)(f))
      def foldRight[A, B](fa: Tannen[F, G, E, A], z: => B)(f: (A, => B) => B): B =
        F.foldRight(fa.f, z)((a, b) => G.bifoldRight(a, b)((_, _) => b)(f))
    }

  implicit def TannenFunctor[F[_], G[_, _], E](implicit F: Functor[F], G: Bifunctor[G]): Functor[Tannen[F, G, E, *]] =
    new Functor[Tannen[F, G, E, *]] {
      def map[A, B](fab: Tannen[F, G, E, A])(f: A => B): Tannen[F, G, E, B] =
        Tannen(F.map(fab.f)(G.rightMap(_)(f)))
    }

  implicit def TannenBifoldable[F[_], G[_, _]](implicit F: Foldable[F], G: Bifoldable[G]): Bifoldable[Tannen[F, G, *, *]] =
    new Bifoldable[Tannen[F, G, *, *]] {
      def bifoldMap[A, B, M](fa: Tannen[F, G, A, B])(f: A => M)(g: B => M)(implicit M: Monoid[M]): M =
        F.foldMap(fa.f)(G.bifoldMap(_)(f)(g))
      def bifoldRight[A, B, C](fa: scalaz.Tannen[F, G, A, B], z: => C)(f: (A, => C) => C)(g: (B, => C) => C): C =
        F.foldRight(fa.f, z)(G.bifoldRight(_, _)(f)(g))
    }

  implicit def TannenBifunctor[F[_], G[_, _]](implicit F: Functor[F], G: Bifunctor[G]): Bifunctor[Tannen[F, G, *, *]] =
    new Bifunctor[Tannen[F, G, *, *]] {
      def bimap[A, B, C, D](fab: Tannen[F, G, A, B])(f: A => C, g: B => D): Tannen[F, G, C, D] =
        Tannen(F.map(fab.f)(G.bimap(_)(f, g)))
    }
}

sealed abstract class TannenInstances extends TannenInstances0 {
  implicit def TannenTraverse[F[_], G[_, _], E](implicit F: Traverse[F], G: Bitraverse[G]): Traverse[Tannen[F, G, E, *]] =
    new Traverse[Tannen[F, G, E, *]] {
      def traverseImpl[H[_], A, B](fa: Tannen[F, G, E, A])(f: A => H[B])(implicit H: Applicative[H]): H[Tannen[F, G, E, B]] =
        H.map(F.traverse(fa.f)(G.bitraverse(_)(H.pure(_))(f)))(Tannen.apply)
    }

  implicit def TannenBitraverse[F[_], G[_, _]](implicit F: Traverse[F], G: Bitraverse[G]): Bitraverse[Tannen[F, G, *, *]] =
    new Bitraverse[Tannen[F, G, *, *]] {
      def bitraverseImpl[H[_], A, B, C, D](fab: Tannen[F, G, A, B])(f: A => H[C], g: B => H[D])(implicit H: Applicative[H]): H[Tannen[F, G, C, D]] =
        H.map(F.traverse(fab.f)(G.bitraverse(_)(f)(g)))(Tannen.apply)
    }

  implicit def TannenEqual[F[_], G[_, _], A, B](implicit F: Equal[F[G[A, B]]]): Equal[Tannen[F, G, A, B]] =
    F.contramap(_.f)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy