Guest User

Untitled

a guest
May 22nd, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.37 KB | None | 0 0
  1. package example
  2.  
  3. import cats._
  4. import cats.free._
  5. import cats.data._
  6. import cats.syntax.flatMap._
  7. import cats.effect.{LiftIO, IO}
  8.  
  9. object Example {
  10. import functors._
  11. import stacks._
  12. import cats.data.Tuple2K._
  13.  
  14. type Effect[A] = EitherK[Logging, Persist, A]
  15.  
  16. type Interp[A] = Tuple2K[CoLogging, CoPersist, A]
  17.  
  18. def prog(implicit L: Logs[Effect], P: Persists[Effect]): Free[Effect, Unit] =
  19. P.store("bar") >> L.log("foo")
  20.  
  21. def interpretEffect(implicit CL: CoLogs[IO], CP: CoPersists[IO]): Cofree[Interp, IO[Unit]] =
  22. Cofree.unfold(IO.pure(())) { a: IO[Unit] => Tuple2K(CoLogging(CL.coLog(a)), CoPersist(CP.coPersist(a))) }
  23. }
  24.  
  25. /////////////////// FREE STUFF
  26.  
  27. case class Logging[A](msg: String, action: A)
  28. case class Persist[A](msg: String, action: A)
  29.  
  30. class Logs[F[_]](implicit I: InjectK[Logging, F]) {
  31. def log(msg: String): Free[F, Unit] = Free.inject[Logging, F](Logging(msg, ()))
  32. }
  33.  
  34. class Persists[F[_]](implicit I: InjectK[Persist, F]) {
  35. def store(msg: String): Free[F, Unit] = Free.inject[Persist, F](Persist(msg, ()))
  36. }
  37.  
  38.  
  39. /////////////////// COFREE STUFF
  40.  
  41. case class CoLogging[A](run: String => A)
  42. case class CoPersist[A](run: String => A)
  43.  
  44. class CoLogs[F[_]: FlatMap](implicit L: LiftIO[F]) {
  45. def coLog(f: F[Unit])(msg: String): F[Unit] = f >> L.liftIO(IO {
  46. println(msg)
  47. })
  48. }
  49.  
  50. class CoPersists[F[_]: FlatMap](implicit L: LiftIO[F]) {
  51. def coPersist(f: F[Unit])(msg: String): F[Unit] = f >> L.liftIO(IO {
  52. println(s"storing $msg")
  53. })
  54. }
  55.  
  56. /////////////////// TYPECLASS INSTANCES
  57.  
  58. object functors {
  59. implicit val fLogging = new Functor[Logging] {
  60. def map[A, B](fa: Logging[A])(f: A => B) = Logging(fa.msg, f(fa.action))
  61. }
  62.  
  63. implicit val fPersist = new Functor[Persist] {
  64. def map[A, B](fa: Persist[A])(f: A => B) = Persist(fa.msg, f(fa.action))
  65. }
  66.  
  67. implicit val fCoLogging = new Functor[CoLogging] {
  68. def map[A, B](fa: CoLogging[A])(f: A => B) = CoLogging(fa.run andThen f)
  69. }
  70.  
  71. implicit val fCoPersist = new Functor[CoPersist] {
  72. def map[A, B](fa: CoPersist[A])(f: A => B) = CoPersist(fa.run andThen f)
  73. }
  74. }
  75.  
  76. object stacks {
  77. implicit def liftCoLogs[F[_]: FlatMap](implicit L: LiftIO[F]) = new CoLogs[F]
  78.  
  79. implicit def liftCoPersists[F[_]: FlatMap](implicit L: LiftIO[F]) = new CoPersists[F]
  80.  
  81. implicit def liftLogging[F[_]](implicit I: InjectK[Logging, F]) = new Logs[F]
  82.  
  83. implicit def liftPersist[F[_]](implicit I: InjectK[Persist, F]) = new Persists[F]
  84. }
Add Comment
Please, Sign In to add comment