Guest User

Untitled

a guest
Jun 21st, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.20 KB | None | 0 0
  1. import cats.~>
  2.  
  3. trait Functor[F[_]] {
  4. def map[A, B](fa: F[A])(f: A => B): F[B]
  5. }
  6.  
  7. trait Monad[F[_]] extends Functor[F] {
  8. def pure[A](a: A): F[A]
  9. def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
  10.  
  11. def map[A, B](fa: F[A])(f: A => B): F[B] =
  12. flatMap(fa)(a => pure(f(a)))
  13. }
  14.  
  15. trait FreeMonad[Free[_[_], _]] {
  16. def instance[F[_]]: Monad[Free[F, ?]]
  17. def foldMap[F[_], G[_]: Monad](f: F ~> G): Free[F, ?] ~> G
  18. }
  19.  
  20. trait MonadError[E, F[_]] {
  21. def pure[A](a: A): F[A]
  22. def raiseError[A](e: E): F[A]
  23. def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
  24. def handleWith[A, B](fa: F[A])(f: E => F[A]): F[A]
  25. }
  26.  
  27. trait FreeMonadError[Free[_, _[_], _]] {
  28. def instance[E, F[_]]: MonadError[E, Free[E, F, ?]]
  29. def foldMap[E, F[_], EE, G[_]](f: F ~> G, g: E => EE)(implicit G: MonadError[EE, G]): Free[E, F, ?] ~> G
  30. }
  31.  
  32. trait Comonad[F[_]] extends Functor[F] {
  33. def extract[A](fa: F[A]): A
  34. def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B]
  35. def map[A, B](fa: F[A])(f: A => B): F[B] = coflatMap(fa)(fa => f(extract(fa)))
  36. def duplicate[A](fa: F[A]): F[F[A]] = coflatMap(fa)(identity)
  37. }
  38.  
  39. trait FreeComonad[Free[_[_], _]] {
  40. def instance[F[_]: Functor]: Comonad[Free[F, ?]]
  41. def extract[E, F[_]: Functor]: Free[F, ?] ~> F
  42. def cofoldMap[F[_]: Functor, G[_]: Comonad, A](ga: G[A])(f: G ~> F): Free[F, A]
  43. }
  44.  
  45. final case class Cofree[S[_], A](head: A, tail: S[Cofree[S, A]])
  46.  
  47. val cofree: FreeComonad[Cofree] = new FreeComonad[Cofree] {
  48. def instance[F[_]](implicit F: Functor[F]): Comonad[Cofree[F, ?]] = new Comonad[Cofree[F, ?]] {
  49. def extract[A](fa: Cofree[F, A]): A = fa.head
  50.  
  51. def coflatMap[A, B](fa: Cofree[F, A])(f: Cofree[F, A] => B): Cofree[F, B] =
  52. Cofree[F, B](f(fa), F.map(fa.tail)(coflatMap(_)(f)))
  53. }
  54.  
  55. def extract[E, F[_]](implicit F: Functor[F]): Cofree[F, ?] ~> F = new (Cofree[F, ?] ~> F) {
  56. def apply[A](fa: Cofree[F, A]): F[A] = F.map(fa.tail)(instance[F].extract)
  57. }
  58.  
  59. def cofoldMap[F[_], G[_], A](ga: G[A])(f: G ~> F)(implicit F: Functor[F], G: Comonad[G]): Cofree[F, A] =
  60. Cofree(G.extract(ga), F.map(f(G.duplicate(ga)))(cofoldMap(_)(f)))
  61. }
  62.  
  63. trait Eq[A] {
  64. def equal(a: A, b: A): Boolean
  65. }
  66. trait FreeEq[Free[_]] {
  67. def instance[A]: Eq[Free[A]]
  68. def cofoldMap[A, B: Eq](f: B => A): B => Free[A]
  69. }
Add Comment
Please, Sign In to add comment