alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Yoneda.scala)

This example Scala source code file (Yoneda.scala) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Scala by Example" TM.

Learn more about this Scala project at its project page.

Java - Scala tags/keywords

coyoneda, functor, ran, yoneda

The Yoneda.scala Scala example source code

package scalaz

/**
 * The cofree functor generated by `F`. The Yoneda lemma says that
 * `Yoneda[F,A]` is isomorphic to `F[A]` for any functor `F`.
 * The homomorphism from `Yoneda[F,A]` to `F[A]` exists even when
 * we have forgotten that `F` is a functor.
 * Can be seen as a partially applied `map` for the functor `F`.
 */
abstract class Yoneda[F[_], A] { yo =>
  def apply[B](f: A => B): F[B]

  /** Converts to `F[A]` even without a `Functor` instance for `F` */
  def run: F[A] = apply(a => a)

  /** Converts to `Coyoneda[F,A]` even without a `Functor` instance for `F` */
  def toCoyoneda: Coyoneda.Aux[F,A,A] = Coyoneda(run)(identity[A])

  /** Simple function composition. Allows map fusion without traversing an `F`. */
  def map[B](f: A => B): Yoneda[F, B] =
    new Yoneda[F, B] {
      def apply[C](g: B => C) = yo(f andThen g)
    }

  import Id._
  /** `Yoneda[F, _]` is the right Kan extension of `F` along `Id` */
  def toRan: Ran[Id, F, A] =
    new Ran[Id, F, A] {
      def apply[B](f: A => B) = yo(f)
    }

  /** `Yoneda` is a comonad in an endofunctor category */
  def extend[G[_]:Functor](f: Yoneda[F,?] ~> G): Yoneda[G,A] =
    Yoneda(f(this))

  /** `Yoneda` is a monad in an endofunctor category */
  def flatMap[G[_]](f: F ~> Yoneda[G,?]): Yoneda[G,A] =
    f(run)
}

object Yoneda {

  /** `Yoneda[F,_]` is a functor for any `F` */
  implicit def yonedaFunctor[F[_]]: Functor[Yoneda[F, ?]] =
    new Functor[Yoneda[F, ?]] {
      def map[A,B](ya: Yoneda[F,A])(f: A => B) = ya map f
    }

  /** `F[A]` converts to `Yoneda[F,A]` for any functor `F` */
  def apply[F[_]:Functor,A](fa: F[A]): Yoneda[F, A] =
    new Yoneda[F, A] {
      def apply[B](f: A => B) = Functor[F].map(fa)(f)
    }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Yoneda.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.