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