Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Horizontal & Vertical Compositions of Natural Transformations
trait Functor[F[_]] {
def map[A, B](as: F[A])(f: A => B): F[B]
}
object Functor {
def apply[F[_]](implicit e: Functor[F]): Functor[F] = e
}
trait ~>[F[_], G[_]] {
def apply[A](x: F[A]): G[A]
}
def comp[A[_], B[_], C[_]](g: B ~> C)(f: A ~> B): A ~> C =
new (A ~> C) {
def apply[X](a: A[X]) = g(f(a))
}
/** Vertical composition of natural transformations */
def vert[F[_]: Functor, F1[_]: Functor, G[_]: Functor, G1[_]: Functor](a: F1 ~> G1)(b: F ~> G): ~>[({ type l[x] = F1[F[x]] })#l, ({ type l[x] = G1[G[x]] })#l] =
new (({ type l[x] = F1[F[x]] })#l ~> ({ type l[x] = G1[G[x]] })#l) {
def apply[A](x: F1[F[A]]) =
a(Functor[F1].map(x)(b(_)))
}
/** Horizontal composition of natural transformations */
def horiz[F[_]: Functor, F1[_]: Functor, G[_]: Functor, G1[_]: Functor](a: F1 ~> G1)(b: F ~> G): ~>[({ type l[x] = F1[F[x]] })#l, ({ type l[x] = G1[G[x]] })#l] =
new (({ type l[x] = F1[F[x]] })#l ~> ({ type l[x] = G1[G[x]] })#l) {
def apply[A](x: F1[F[A]]): G1[G[A]] =
Functor[G1].map(a(x))(b(_))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.