Skip to content

Instantly share code, notes, and snippets.

@gregnwosu
Forked from Fristi/FreeActor.scala
Last active August 29, 2015 14:19
Show Gist options
  • Save gregnwosu/26cbe11d432ec440e9aa to your computer and use it in GitHub Desktop.
Save gregnwosu/26cbe11d432ec440e9aa to your computer and use it in GitHub Desktop.
package nl.mdj.fpinscala
import akka.actor.Actor.Receive
import akka.actor.{Props, Actor, ActorSystem, ActorRef}
import akka.pattern.ask
import akka.util.Timeout
import nl.mdj.fpinscala.KeyValueStore.ListKeys
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scalaz._
object FreeActorMain extends App {
import scalaz.std.scalaFuture
val program = {
for {
_ <- KeyValueStore.put("value.1", "nee")
_ <- KeyValueStore.put("value.2", "ja")
keys <- KeyValueStore.listKeys
value1 <- KeyValueStore.get(keys.head)
exists <- KeyValueStore.exists(keys.head)
} yield keys -> value1
}
val system = ActorSystem()
val actor = system.actorOf(KeyValueStore.props)
val nat = KeyValueStore.interperter(actor)(Timeout(2.second))
val result = Free.runFC(program)(nat)(scalaFuture.futureInstance(scala.concurrent.ExecutionContext.global))
println(Await.result(result, 1.second))
}
class KeyValueStore extends Actor {
var map = Map.empty[String, Any]
override def receive: Receive = {
case u:KeyValueStore.Get => sender ! map.get(u.key)
case u:KeyValueStore.Exists => sender ! map.contains(u.key)
case ListKeys => sender ! map.keys.toList
case u:KeyValueStore.Put =>
if(!map.contains(u.key)) {
map += u.key -> u.value
sender ! true
} else {
sender ! false
}
}
}
object KeyValueStore {
sealed trait KeyValue[A]
case class Put(key: String, value: String) extends KeyValue[Boolean]
case class Exists(key: String) extends KeyValue[Boolean]
case class Get(key: String) extends KeyValue[Option[String]]
case object ListKeys extends KeyValue[List[String]]
type KvS[A] = Free.FreeC[KeyValue, A]
def put[A](key: String, value: String) = Free.liftFC(Put(key, value))
def get[A](key: String) = Free.liftFC(Get(key))
def exists[A](key: String) = Free.liftFC(Exists(key))
def listKeys = Free.liftFC(ListKeys)
def props = Props(new KeyValueStore())
def interperter(actorRef: ActorRef)(implicit timeout: Timeout) = new (KeyValue ~> Future) {
override def apply[A](fa: KeyValue[A]): Future[A] =
actorRef.ask(fa).asInstanceOf[Future[A]]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment