Başımı State monad'ın etrafına doyorum. Önemsiz örnekler anlamak kolaydır. Artık alan nesnelerinin kompozit olduğu gerçek bir dünyaya geçiyorum. Örneğin, aşağıdaki alanı nesneleri (onlar çok mantıklı, sırf örnek yapmazlar) ile:Scala State monad - farklı durum türlerini birleştiriyor
case class Master(workers: Map[String, Worker])
case class Worker(elapsed: Long, result: Vector[String])
case class Message(workerId: String, work: String, elapsed: Long)
State[S, +A]
monad içinde Worker
S
olarak türlerini dikkate alındığında bu gibi birkaç combinators yazmak için oldukça kolaydır:
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.
Bunları Master
durum kombinatorörleri ile birleştirmenin deyimsel yolu nedir? Örneğin.
type MasterState[+A] = State[Master, A]
def updateAndGetElapsedTime(message: Message): MasterState[Option[Long]]
ben şöyle uygulayabilirsiniz:
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))
}
}
Ne sevmiyorum ben manuel geçen transformatör içindeki Devlet monad çalıştırmak zorunda olmasıdır. Gerçek dünya örneğim biraz daha ilgili. Bu yaklaşımla, hızla dağınık hale gelir.
Bu tür artımlı güncelleştirmeleri çalıştırmak için daha fazla deyim var mı?
Güzel soru! Scalaz gibi bazı somut “Devlet” uygulamalarına mı atıf yapıyorsunuz? – Odomontois
Kesinlikle 'LensT' kullanımı için güzel bir örnek gibi görünüyor, bazı uzmanların cevabını görmek için sabırsızlanıyorum. – Odomontois