Skip to content

Instantly share code, notes, and snippets.

@Baccata
Last active April 1, 2017 20:17
Show Gist options
  • Save Baccata/e4a200443448f6b09c9c7b6c405a3d89 to your computer and use it in GitHub Desktop.
Save Baccata/e4a200443448f6b09c9c7b6c405a3d89 to your computer and use it in GitHub Desktop.
Transforming a pure stateful computation into an asynchronous effectful computation
import akka.actor.{ Actor, ActorSystem, Props }
import akka.util.Timeout
import cats._
import cats.data.State
class ActorInterpreter[G[_], StateData](
actorSystem: ActorSystem,
initialData: StateData,
stateInterpreter: G ~> Lambda[A => State[StateData, A]]
)(implicit t: Timeout, ec: ExecutionContext)
extends (G ~> Future) {
case class Request[T](value: G[T], promise: Promise[T])
val actor = actorSystem.actorOf(Proxy.props())
override def apply[A](fa: G[A]): Future[A] = {
val promise = Promise[A]
actor ! Request(fa, promise)
promise.future
}
object Proxy {
def props(): Props = Props(new Proxy())
}
private class Proxy extends Actor {
var data: StateData = initialData
override def receive: Receive = {
case Request(instruction, promise) =>
val res = stateInterpreter.apply(instruction).run(data)
data = res.value._1
promise.success(res.value._2)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment