Last active
November 16, 2016 11:29
-
-
Save Baccata/dd6bed5246a24976c9a45507e9bb899a to your computer and use it in GitHub Desktop.
This file contains 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
import cats.free.Free | |
import cats.{ Monad, ~> } | |
object KVStoreExample { | |
sealed trait KVStore[A] | |
case class Put[T](key: String, value: T) extends KVStore[Unit] | |
case class Get[T](key: String) extends KVStore[Option[T]] | |
object KVStore { | |
trait Interface[M[_]] { | |
def put[T](key: String, value: T): M[Unit] | |
def get[T](key: String): M[Option[T]] | |
} | |
trait Interp[M[_]] extends (KVStore ~> M) with Interface[M] { | |
def run[A](f: Free[KVStore, A])(implicit monad: Monad[M]): M[A] = | |
f.foldMap(this) | |
} | |
object Interp { | |
def fromArrow[M[_]](arrow: KVStore ~> M): Interp[M] = | |
new ReverseRoutedInterp[M](arrow) | |
} | |
//User has to implement the methods | |
trait RoutedInterp[M[_]] extends Interp[M] { | |
override final def apply[A](fa: KVStore[A]): M[A] = fa match { | |
case Put(key, value) => put(key, value) | |
case Get(key) => get(key) | |
} | |
} | |
//User has to construct using an arrow | |
case class ReverseRoutedInterp[M[_]](underlying: KVStore ~> M) | |
extends Interp[M] { | |
override final def put[T](key: String, value: T): M[Unit] = | |
apply(Put(key, value)) | |
override final def get[T](key: String): M[Option[T]] = apply(Get(key)) | |
override final def apply[A](fa: KVStore[A]): M[A] = underlying.apply(fa) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment