Owijam głowę wokół Monady stanu. Proste przykłady są łatwe do zrozumienia. Przechodzę teraz do rzeczywistego przypadku, w którym obiekty domeny są złożone. Na przykład, z następujących obiektów domeny (nie ma większego sensu, po prostu zwykły przykład):Moneta Scala State - łącząca różne typy stanów
case class Master(workers: Map[String, Worker])
case class Worker(elapsed: Long, result: Vector[String])
case class Message(workerId: String, work: String, elapsed: Long)
Zważywszy Worker
jak S
typów w State[S, +A]
monady to dość łatwe do napisania kilku kombinatorów, takie jak:
type WorkerState[+A] = State[Worker, A]
def update(message: Message): WorkerState[Unit] = State.modify { w =>
w.copy(elapsed = w.elapsed + message.elapsed,
result = w.result :+ message.work)
}
def getWork: WorkerState[Vector[String]] = State { w => (w.result, w) }
def getElapsed: WorkerState[Long] = State { w => (w.elapsed, w) }
def updateAndGetElapsed(message: Message): WorkerState[Long] = for {
_ <- update(message)
elapsed <- getElapsed
} yield elapsed
// etc.
Jaki jest idiomatyczny sposób łączenia ich z kombinatorami stanu Master
? na przykład
type MasterState[+A] = State[Master, A]
def updateAndGetElapsedTime(message: Message): MasterState[Option[Long]]
mogę wdrożyć to tak:
def updateAndGetElapsedTime(message: Message): MasterState[Option[Long]] =
State { m =>
m.workers.get(message.workerId) match {
case None => (None, m)
case Some(w) =>
val (t, newW) = updateAndGetElapsed(message).run(w)
(Some(t), m.copy(m.workers.updated(message.workerId, newW))
}
}
Co mi się nie podoba to, że będę musiał ręcznie uruchomić monady State wewnątrz ostatniej transformatora. Mój przykład z prawdziwego świata jest nieco bardziej zaangażowany. Dzięki takiemu podejściu szybko się brudzi.
Czy istnieje bardziej idiomatyczny sposób uruchamiania tego rodzaju przyrostowych aktualizacji?
Ładne pytanie! Czy odwołujesz się do jakiejś konkretnej implementacji 'State', takiej jak' scalaz'? – Odomontois
Zdecydowanie wygląda na ładny przykład użycia 'LensT', nie może się doczekać odpowiedzi eksperta. – Odomontois