Sto avvolgendo la mia testa attorno monade di stato. Gli esempi banali sono facili da capire. Ora sto passando a un caso reale in cui gli oggetti del dominio sono compositi. Ad esempio, con i seguenti oggetti di dominio (che non ha molto senso, solo pura esempio):Scala monade stato - combinazione di diversi tipi di stato
case class Master(workers: Map[String, Worker])
case class Worker(elapsed: Long, result: Vector[String])
case class Message(workerId: String, work: String, elapsed: Long)
Considerando Worker
come S
tipi di State[S, +A]
monade è abbastanza facile scrivere un paio di combinatori come questi:
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.
Qual è il modo idiomatico di combinarli con i combinatori di stato Master
? per esempio.
type MasterState[+A] = State[Master, A]
def updateAndGetElapsedTime(message: Message): MasterState[Option[Long]]
posso realizzare questo modo:
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))
}
}
Quello che non mi piace è che devo eseguire manualmente la monade Stato all'interno dell'ultimo trasformatore. Il mio esempio del mondo reale è un po 'più coinvolto. Con questo approccio diventa rapidamente disordinato.
C'è altro modo idiomatico per eseguire questo tipo di aggiornamenti incrementali?
Bella domanda! Ti riferisci ad alcune concrete implementazioni di 'State' come' scalaz'? – Odomontois
Sembra decisamente un bell'esempio per l'uso di 'LensT', non vedo l'ora di vedere la risposta di un esperto. – Odomontois