私はFreeMonadsを使用して私のサービスのためのインタプリタを実装する方法を学ぼうとしています。アクションをチェーン化してScalazと一緒に解釈するにはどうすればいいですか?
私は
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]
とアクション
type LogActionF[A] = Free[LogAction, A]
type ServiceActionF[A] = Free[ServiceAction, A]
次のモナドがあると、私はこのように私のサービスを定義します。
trait PointAccrualService {
def consume(cmd: AccruePoints): ServiceActionF[AccruePointModel] = Free.liftF(ConsumeCommand(cmd))
def emit(evt: PointsAccruedEvent) : ServiceActionF[PointsAccruedEvent] = Free.liftF(CreateEvent(evt))
}
と
trait LogService {
def info(msg: String) : LogActionF[Unit] = Free.liftF(Info(msg))
def error(msg: String) : LogActionF[Unit] = Free.liftF(Error(msg))
}
各
object LogService extends LogService
object PointAccrualService extends PointAccrualService
の対象と
マイLogServiceInterpreter
はこのようなものです:
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")
}
}
同様に、私のPointAccuralServiceInterpreter
はこのようなものです:
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)
}
}
}
}
私のロジックは、私が欲しい、簡単ですログに記録し、私のコマンドを消費して、イベントを作成する、ソーシングのようなイベントのようなもの:
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
このコードは実際にはコンパイルされません。
ここから何をすればよいですか?私はCoproductを使ってそれらを連鎖させ、私の通訳に給油することによってこの論理を実行することになっていると思います。
私はここ https://groups.google.com/forum/#!topic/scalaz/sHxFsFpE86c
何かを見つけたり、私がそう Folding a list of different types using Shapeless in Scala
彼らはあまりにも複雑でやって型崩れを使用することができると述べています。私が望むのは、自分のロジックを定義した後、どのように実行すればよいのでしょうか?
私は答えのために十分な詳細をここに入れています。私は本当にこれを学びたい。ありがとう
:ここ
は完全なコードです。 – pedrofurla
申し訳ありませんが、コードを追加しましょう。私は他の人と一緒に昼食のために急いだ。私は体にもっと入れておくべきだった – sowen