Skip to content

Instantly share code, notes, and snippets.

@bqm
Last active May 2, 2016 18:27
Show Gist options
  • Save bqm/e8e28c06311be8d76071729dcaf5b836 to your computer and use it in GitHub Desktop.
Save bqm/e8e28c06311be8d76071729dcaf5b836 to your computer and use it in GitHub Desktop.
A Key value store DSL client code example of https://gist.github.com/bqm/bee72c18fa4baa708f7cf2b146bbc872
import cats.{Id, Functor, Monad, ~>}
import cats.std.function._
import cats.syntax.cartesian._
sealed trait KVS[A]
case class Put[A](key: String, value: String, a: A) extends KVS[A]
case class Get[A](key: String, a: String => A) extends KVS[A]
type Dsl[A] = ApFree[KVS, A]
implicit val kvsFunctor: Functor[KVS] = new Functor[KVS] {
def map[A, B](a: KVS[A])(f: A => B) = a match {
case Put(k, v, next) => Put(k, v, f(next))
case Get(k, onResult) => Get(k, onResult andThen f)
}
}
def put(key: String, value: String): Dsl[Unit] = {
ApFree.liftF(Put(key, value, ()))
}
def get(key: String): Dsl[String] = {
ApFree.liftF(Get(key, str => str))
}
val frenchHelloPut = put("frenchHello", "Bonjour")
val germanHelloPut = put("germanHello", "Hallo")
val spanishHelloPut = put("spanishHello", "Hola")
val hellos: Dsl[(String, String, String)] = for {
_ <- frenchHelloPut.join(germanHelloPut).join(spanishHelloPut)
frenchHelloGet = get("frenchHello")
germanHelloGet = get("germanHello")
spanishHelloGet = get("spanishHello")
res <- frenchHelloGet.join(germanHelloGet).join(spanishHelloGet)
} yield (res._1._1, res._1._2, res._2)
type KvsDsl[A] = KVS[Dsl[A]]
type IdDsl[A] = Id[Dsl[A]]
import scala.collection.mutable.{Map => MMap}
val myStore = MMap.empty[String, String]
def interpret[A](
dsl: Dsl[A]): Id[A] = dsl.fold2(
new (KvsDsl ~> IdDsl) {
def apply[B](fa: KVS[Dsl[B]]): Id[Dsl[B]] = fa match {
case Get(key, f) => f(myStore(key))
case Put(key, value, f) => {
myStore.update(key, value)
f
}
}
}
)
// interpret(hellos)
// res1: (String, String, String) = ("Bonjour", "Hallo", "Hola")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment