Ich versuche zu lernen, wie man FreeMonads benutzt, um Dolmetscher für meine Dienste zu implementieren.Wie kette ich Aktionen und interpretiere sie zusammen mit Scalaz?
nehme ich
sealed trait ServiceAction[T] extends Product with Serializable
case class ConsumeCommand(cmd: AccruePoints) extends ServiceAction[AccruePointModel]
case class CreateEvent(evt: PointsAccruedEvent) extends ServiceAction[PointsAccruedEvent]
sealed trait LogAction[T] extends Product with Serializable
case class Info(msg: String) extends LogAction[Unit]
case class Error(msg: String) extends LogAction[Unit]
und eine Monade der Aktion
type LogActionF[A] = Free[LogAction, A]
type ServiceActionF[A] = Free[ServiceAction, A]
Als nächstes haben, definiere ich meinen Dienst so:
trait PointAccrualService {
def consume(cmd: AccruePoints): ServiceActionF[AccruePointModel] = Free.liftF(ConsumeCommand(cmd))
def emit(evt: PointsAccruedEvent) : ServiceActionF[PointsAccruedEvent] = Free.liftF(CreateEvent(evt))
}
und
trait LogService {
def info(msg: String) : LogActionF[Unit] = Free.liftF(Info(msg))
def error(msg: String) : LogActionF[Unit] = Free.liftF(Error(msg))
}
mit einem Objekt jedes
object LogService extends LogService
object PointAccrualService extends PointAccrualService
Mein LogServiceInterpreter
ist wie folgt:
case class LogServiceConsoleInterpreter() extends LogServiceInterpreter {
def apply[A](action: LogActionF[A]): Task[A] = action.foldMap(handler)
protected def handler = new (LogAction ~> Task) {
override def apply[A](fa: LogAction[A]) = fa match {
case Info(m) =>
now(info(m))
case Error(m) =>
now(error(m))
}
}
def info(msg: String): Unit = {
println(s"INFO: $msg")
}
def error(msg: String): Unit = {
println(s"ERROR: $msg")
}
}
Und mein PointAccuralServiceInterpreter
ist wie folgt:
case class PointAccuralServiceInterpreter() {
def apply[A] (action: ServiceActionF[A]) : Task[A] = action.foldMap(handler)
protected def handler = new (ServiceAction ~> Task) {
override def apply[A](fa: ServiceAction[A]): Task[A] = fa match {
case ConsumeCommand(cmd) => {
println("Service ConsumeCommand:" + cmd)
now(cmd)
}
case CreateEvent(evt) => {
println("Service CreateEvent:" + evt)
now(evt)
}
}
}
}
Meine Logik einfach ist, ich will um zu loggen und meinen Befehl zu konsumieren und dann ein Ereignis zu erstellen, ähnlich einer Ereignisquelle:
val ret = for {
_ <- logService.info("Command: " + cmd)
model <- service.consume(cmd)
_ <- logService.info("Model: " + model)
evt <- service.emit(model.toEvent("200", "Event Sent"))
_ <- logService.info("Event:" + evt)
} yield evt
Dieser Code wird nicht einmal tatsächlich kompiliert.
Was soll ich von hier aus machen? Ich denke, ich sollte Coproduct benutzen, um sie zu verketten und dieses Stück Logik auszuführen, indem ich meinen Dolmetscher füttere.
fand ich etwas hier https://groups.google.com/forum/#!topic/scalaz/sHxFsFpE86c
oder es gesagt ich Shapeless so Folding a list of different types using Shapeless in Scala
Sie sind zu tun, können alle zu kompliziert. Alles was ich will ist, nachdem ich meine Logik definiert habe, wie führe ich sie aus?
Ich hoffe, ich habe genug Details hier für eine Antwort. Ich möchte das wirklich lernen. Danke
Ihre Frage ist überhaupt nicht klar. – pedrofurla
Entschuldigung, lass mich mehr Code hinzufügen. Ich stürzte mit anderen Leuten zu Mittag.Ich hätte mehr in den Körper tun sollen – sowen