Created
April 19, 2016 03:30
-
-
Save blast-hardcheese/eab0b0423977f7d84ba103518e161974 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package se.hardchee.Pickr | |
import scala.language.higherKinds | |
import scala.language.implicitConversions | |
import scalaz._ | |
import scalaz.std.function._ | |
import scalaz.syntax.monad._ | |
import se.hardchee.Pickr.algebras._ | |
object Main extends App { | |
sealed trait Auth[T] | |
case object IsLoggedIn extends Auth[Boolean] | |
case object LogIn extends Auth[Unit] | |
case object LogOut extends Auth[Unit] | |
sealed trait TodoModel[T] | |
case object GetItem extends TodoModel[String] | |
type AuthStore[A] = State[Boolean, A] | |
object AuthInterpreter extends (Auth ~> AuthStore) { | |
def apply[T](fa: Auth[T]) = { | |
fa match { | |
case IsLoggedIn => State { s => (s, s) } | |
case LogIn => State { s => (true, ()) } | |
case LogOut => State { s => (false, ()) } | |
} | |
} | |
} | |
object TodoModelInterpreter extends (TodoModel ~> AuthStore) { | |
def apply[T](fa: TodoModel[T]) = { | |
fa match { | |
case GetItem => State { s => (s, "Super secret string!") } | |
} | |
} | |
} | |
def prog[F[_]](implicit A: Inject[Auth, F], T: Inject[TodoModel, F]): Free.FreeC[F, String] = { | |
for { | |
loggedIn <- IsLoggedIn | |
item <- if (loggedIn) GetItem.liftI else LogOut.liftI | |
} yield item | |
} | |
type PROG[A] = Coproduct[Auth, TodoModel, A] | |
val interpreter: PROG ~> AuthStore = AuthInterpreter or TodoModelInterpreter | |
prog[PROG].foldMap(Coyoneda.liftTF(interpreter)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package se.hardchee.Pickr | |
import scala.language.higherKinds | |
import scala.language.implicitConversions | |
import scalaz.{ Coproduct, Free, Inject, ~>, \/-, -\/ } | |
package object algebras { | |
implicit def liftFCInj[A, P[_], F[_]](x: P[A])(implicit I: Inject[P, F]): Free.FreeC[F, A] = { | |
Free.liftFC(I.inj(x)) | |
} | |
implicit class RichFreeC[P[_], A](x: P[A]) { | |
def liftI[F[_]](implicit I: Inject[P, F]): Free.FreeC[F, A] = liftFCInj(x) | |
} | |
// enhancing natural transformations with an or operator | |
implicit class NaturalTransformationOrOps[F[_], H[_]](private val f2h: F ~> H) extends AnyVal { | |
type Copro[F[_], G[_]] = { type f[x] = Coproduct[F, G, x] } // just for better readability | |
// given F ~> H and G ~> H we derive Copro[F, G]#f ~> H | |
def or[G[_]](g2h: G ~> H): Copro[F, G]#f ~> H = | |
new (Copro[F, G]#f ~> H) { | |
def apply[A](c: Coproduct[F, G, A]): H[A] = c.run match { | |
case -\/(fa) => f2h(fa) | |
case \/-(ga) => g2h(ga) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment