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

scalaz.Representable.scala Maven / Gradle / Ivy

The newest version!
package scalaz

/** Representable functors, that is to say, those with isomorphisms to
  * and from `[a](X => a)`.  As such, all typeclasses and operations on
  * `[a](X => a)`, that is, fixed in `X`, can be trivially derived for
  * `F`.
  */
abstract class Representable[F[_], X](implicit val F: Functor[F]) {
  def rep[A](f: X => A): F[A]
  def unrep[A](f: F[A]): X => A

  trait RepresentableLaw {
    /** `rep compose unrep` is vacuous. */
    def repUnrep[A](f: F[A])(implicit E: Equal[F[A]]): Boolean =
      E.equal(rep(unrep(f)), f)
    /** `unrep compose rep` is vacuous. */
    def unrepRep[A](f: X => A, x: X)(implicit E: Equal[A]): Boolean =
      E.equal(unrep(rep(f))(x), f(x))
  }

  def representableLaw: RepresentableLaw = new RepresentableLaw {}
}

sealed abstract class RepresentableInstances {
  import scalaz.std.function._

  /** The identity representable. */
  implicit def readerRepresentable[E]: Representable[E => *, E] =
    new Representable[E => *, E] {
      def rep[A](f: E => A) = f
      def unrep[A](f: E => A) = f
    }

  implicit def curryRepresentable[E]: Representable[E => *, (E, Unit)] =
    new Representable[E => *, (E, Unit)] {
      def rep[A](f: ((E, Unit)) => A): E => A = e => f((e, ()))
      def unrep[A](f: E => A): ((E, Unit)) => A = e => f(e._1)
    }

  implicit val f0Representable: Representable[Function0, Unit] =
    new Representable[Function0, Unit] {
      def rep[A](f: Unit => A) = () => f(())
      def unrep[A](f: () => A) = u => f()
    }
}

object Representable extends RepresentableInstances

/** Corepresentable functors */
abstract class Corepresentable[F[_]: Contravariant, X]() {
  def corep[A](f: A => X): F[A]
  def uncorep[A](f: F[A]): A => X

  trait CorepresentableLaw {
    def corepUncorep[A](f: F[A])(implicit E: Equal[F[A]]): Boolean =
      E.equal(corep(uncorep(f)), f)
    def uncorepCorep[A](f: A => X, a: A)(implicit E: Equal[X]): Boolean =
      E.equal(uncorep(corep(f))(a), f(a))
  }

  def corepresentableLaw: CorepresentableLaw = new CorepresentableLaw {}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy