Guest User

Untitled

a guest
Nov 16th, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.68 KB | None | 0 0
  1. import scalaz._, Scalaz._
  2.  
  3. // Adjunction between `F` and `G` means there is an
  4. // isomorphism between `A => G[B]` and `F[A] => B`.
  5. trait Adjunction[F[_],G[_]] {
  6. def leftAdjunct[A, B](a: A)(f: F[A] => B): G[B]
  7. def rightAdjunct[A, B](a: F[A])(f: A => G[B]): B
  8. }
  9.  
  10. // Adjunction between free and forgetful functor.
  11. // We can think of the forgetful functor as taking `P a => a` to just `a`.
  12. // That is, given `P[A]`, `Forget[P,A] = A`.
  13. trait FreeForgetAdjunction[F[_], P[_]] {
  14. def left[A,B](f: F[A] => B): A => B
  15. def right[A,B:P](f: A => B): F[A] => B
  16. }
  17.  
  18. // Class for pointed sets
  19. case class Pointed[P](point: P)
  20.  
  21. object Pointed {
  22. def apply[P](implicit P: Pointed[P]): Pointed[P] = P
  23. }
  24.  
  25. // `Option[A]` is the free pointed set on `A`.
  26. // It is left-adjoint to the functor that "loses the point".
  27. // The `unit` is `Some` and the `counit` is `fold`.
  28. new FreeForgetAdjunction[Option, Pointed] {
  29. def left[A,B](f: Option[A] => B): A => B =
  30. a => f(Some(a))
  31. def right[A,B:Pointed](f: A => B): Option[A] => B =
  32. _.fold(Pointed[B].point)(f)
  33. }
  34.  
  35. // `List[A]` is the free monoid on `A`.
  36. // It is left-adjoint to the functor that takes `Monoid[M]` to just `M`,
  37. // as witnessed by the singleton list constructor and `foldMap`.
  38. new FreeForgetAdjunction[List, Monoid] {
  39. def left[A,B](f: List[A] => B): A => B =
  40. a => f(List(a))
  41. def right[A,B:Monoid](f: A => B): List[A] => B =
  42. _.foldRight(Monoid[B].zero)((a, b) => Monoid[B].append(f(a), b))
  43. }
  44.  
  45. // The higher-kinded case
  46. trait FreeForgetAdjunction[C[_[_],_], P[_[_]]] {
  47. def left[F[_],G[_]](f: C[F,?] ~> G): F ~> G
  48. def right[F[_],G[_]:P](f: F ~> G): C[F,?] ~> G
  49. }
  50.  
  51. // `Free[F,?]` is the free monad on `F`
  52. // It is left-adjoint to the functor that takes `Monad[M]` to just `M`,
  53. // as witnessed by `liftF` and `foldMap`
  54. new FreeForgetAdjunction[Free, Monad] {
  55. def left[F[_],G[_]](f: Free[F,?] ~> G): F ~> G = new (F ~> G) {
  56. def apply[A](a: F[A]) = f(Free.liftF(a))
  57. }
  58. def right[F[_],G[_]:Monad](f: F ~> G): Free[F,?] ~> G = new (Free[F,?] ~> G) {
  59. def apply[A](a: Free[F,A]) = a.foldMap(f)
  60. }
  61. }
  62.  
  63.  
  64. ////////////
  65.  
  66. // Monoid adjunction:
  67. //
  68. // Free -| Forget
  69. //
  70. // F -| G
  71. //
  72. // F[A] for a type A is the free monoid generated by A.
  73. // G[M] for a monoid M is the type M, forgetting that it's a monoid.
  74.  
  75.  
  76. // Adjunction between free and forgetful functor.
  77. // We can think of the forgetful functor as taking `P a => a` to just `a`.
  78. // That is, given `P[A]`, `Forget[P,A] = A`.
  79. trait FreeForgetAdjunction[F[_], P[_]] {
  80. def left[A,B](f: F[A] => B): A => B
  81. def right[A,B:P](f: A => B): F[A] => B
  82. }
  83.  
  84. // `List[A]` is the free monoid on `A`.
  85. // It is left-adjoint to the functor that takes `Monoid[M]` to just `M`,
  86. // as witnessed by the singleton list constructor and `foldMap`.
  87. new FreeForgetAdjunction[List, Monoid] {
  88. def left[A,B](f: List[A] => B): A => B =
  89. a => f(List(a))
  90. def right[A,B:Monoid](f: A => B): List[A] => B =
  91. _.foldRight(Monoid[B].zero)((a, b) => Monoid[B].append(f(a), b))
  92.  
  93. def unit[A](a: A): List[A] =
  94. left(identity[List[A]])(a)
  95.  
  96. def counit[A:Monoid](as: List[A]): A =
  97. right(identity[A])(as)
  98.  
  99. // So the counit is `fold` in a monoid!
  100. // `List` is a comonad in the category of monoids.
  101. //
  102. // What does the duplicate look like?
  103. // It gives us the "substructure" of the free monoid.
  104. // So, one list per element in the original list.
  105. def duplicate[A:Monoid](as: List[A]): List[List[A]] =
  106. as.map(unit(_))
  107. }
  108.  
  109. // The higher-kinded case
  110. trait FreeForgetAdjunction[C[_[_],_], P[_[_]]] {
  111. def left[F[_],G[_]](f: C[F,?] ~> G): F ~> G
  112. def right[F[_],G[_]:P](f: F ~> G): C[F,?] ~> G
  113. }
  114.  
  115. trait CofreeForgetAdjunction[C[_[_],_], P[_[_]]] {
  116. def left[F[_]:P,G[_]](f: F ~> G): F ~> C[G,?]
  117. def right[F[_],G[_]](f: F ~> C[G,?]): F ~> G
  118. }
  119.  
  120. object CofreeComonad extends CofreeForgetAdjunction[Cofree, Comonad] {
  121. def left[F[_]:Comonad,G[_]](f: F ~> G): F ~> Cofree[G,?] = new (F ~> Cofree[G,?]) {
  122. def apply[A](as: F[A]) = mapUnfold(as)(f)
  123. }
  124. // if `f` generates a G-branching stream, then we get a function `F ~> G` that
  125. // "skims" the head of all the branches
  126. def right[F[_]:Functor,G[_]](f: F ~> Cofree[G,?]): F ~> G = new (F ~> G) {
  127. def apply[A](as: F[A]) = f(as).tail.map(_.head)
  128. }
  129.  
  130. // The unit takes `F[A]` to `Cofree[F,A]` for any comonad `F`
  131. // `Cofree` is a monad in the category of comonads.
  132. // The head of the cofree is the counit of the `F` and its tail is `unit` extended over the `F`.
  133. def unit[F[_]:Comonad]: F ~> Cofree[F,A] =
  134. left(NaturalTransformation.identity[F])
  135.  
  136. // The counit here is the head of the tail.
  137. // Comonad in an endofunctor category
  138. def counit[F[_]]: Cofree[F,A] ~> F =
  139. right(NaturalTransformation.identity[Cofree[F,?]])
  140. }
  141.  
  142. def mapUnfold[F[_],W[_],A](z: W[A])(f: W ~> F)(implicit W: Comonad[W]): Cofree[F,A]
Add Comment
Please, Sign In to add comment