/core/src/main/scala/scalaz/Category.scala

http://github.com/scalaz/scalaz · Scala · 73 lines · 39 code · 13 blank · 21 comment · 0 complexity · 2428d604150fe74c374d3b2ed3c95945 MD5 · raw file

  1. package scalaz
  2. ////
  3. /**
  4. * [[scalaz.Compose]] with identity.
  5. *
  6. * @see [[scalaz.Category.CategoryLaw]]
  7. */
  8. ////
  9. trait Category[=>:[_, _]] extends Compose[=>:] { self =>
  10. ////
  11. // TODO GeneralizedCategory, GeneralizedFunctor, et al, from Scalaz6 ?
  12. /** The left and right identity over `compose`. */
  13. def id[A]: A =>: A
  14. /** `monoid`, but universally quantified. */
  15. def empty: PlusEmpty[λ[α => α =>: α]] =
  16. new PlusEmpty[λ[α => α =>: α]] with ComposePlus {
  17. def empty[A] = id
  18. }
  19. /** The endomorphism monoid, where `zero`=`id` and
  20. * `append`=`compose`.
  21. */
  22. def monoid[A]: Monoid[A =>: A] =
  23. new Monoid[A =>: A] with ComposeSemigroup[A] {
  24. def zero = id
  25. }
  26. trait CategoryLaw extends ComposeLaw {
  27. /** `_ <<< id` is vacuous. */
  28. def leftIdentity[A, B](ab: (A =>: B))(implicit E: Equal[A =>: B]): Boolean = {
  29. val ab1 = compose(ab, id[A])
  30. E.equal(ab, ab1)
  31. }
  32. /** `id <<< _` is vacuous. */
  33. def rightIdentity[A, B](ab: (A =>: B))(implicit E: Equal[A =>: B]): Boolean = {
  34. val ab1 = compose(id[B], ab)
  35. E.equal(ab, ab1)
  36. }
  37. }
  38. def categoryLaw = new CategoryLaw {}
  39. ////
  40. val categorySyntax: scalaz.syntax.CategorySyntax[=>:] =
  41. new scalaz.syntax.CategorySyntax[=>:] { def F = Category.this }
  42. }
  43. object Category {
  44. @inline def apply[F[_, _]](implicit F: Category[F]): Category[F] = F
  45. import Isomorphism._
  46. def fromIso[F[_, _], G[_, _]](D: F <~~> G)(implicit E: Category[G]): Category[F] =
  47. new IsomorphismCategory[F, G] {
  48. override def G: Category[G] = E
  49. override def iso: F <~~> G = D
  50. }
  51. ////
  52. ////
  53. }
  54. trait IsomorphismCategory[F[_, _], G[_, _]] extends Category[F] with IsomorphismCompose[F, G]{
  55. implicit def G: Category[G]
  56. ////
  57. override def id[A]: F[A, A] =
  58. iso.from(G.id)
  59. ////
  60. }