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