Ich wickle meinen Kopf um State Monad. Triviale Beispiele sind leicht zu verstehen. Ich gehe jetzt zu einem realen Fall, in dem die Domänenobjekte zusammengesetzt sind. Zum Beispiel mit den folgenden Domänenobjekten (sie nicht viel Sinn machen, nur schiere Beispiel):Scala State Monade - Kombinieren verschiedener State-Typen
case class Master(workers: Map[String, Worker])
case class Worker(elapsed: Long, result: Vector[String])
case class Message(workerId: String, work: String, elapsed: Long)
Unter Berücksichtigung Worker
als S
Arten in State[S, +A]
Monade ist es ganz einfach, ein paar combinators wie diese zu schreiben:
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.
Was ist der idiomatische Weg, diese mit den Master
State Kombinatoren zu kombinieren? z.B.
type MasterState[+A] = State[Master, A]
def updateAndGetElapsedTime(message: Message): MasterState[Option[Long]]
Ich kann dies umzusetzen etwa so:
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))
}
}
Was Ich mag nicht, dass ich manuell den Staat Monade innerhalb des letzten Transformator laufen. Mein Beispiel aus der realen Welt ist ein bisschen mehr involviert. Mit diesem Ansatz wird es schnell unordentlich.
Gibt es mehr idiomatische Möglichkeit, diese Art von inkrementellen Updates auszuführen?
Nette Frage! Beziehen Sie sich auf eine konkrete "State" Implementierung wie "Scalaz"? – Odomontois
Es ist definitiv ein schönes Beispiel für 'LensT', ich kann es kaum erwarten, die Antwort eines Experten zu sehen. – Odomontois