Nachdem ich Kapitel 6 von Functional Programming in Scala gelesen habe und versuche, die Zustands-Monade zu verstehen, habe ich eine Frage bezüglich der Umhüllung einer Nebeneffekt-Klasse.Einpacken einer Klasse mit Nebenwirkungen
Angenommen, ich habe eine Klasse, die sich selbst irgendwie modifiziert.
class SideEffect(x:Int) {
var value = x
def modifyValue(newValue:Int):Unit = { value = newValue }
}
Mein Verständnis ist, dass, wenn wir dies in einem Staat Monade, wie unten gewickelt, es wäre immer noch das Original macht den Punkt der Verpackung es strittig zu ändern.
case class State[S,+A](run: S => (A, S)) { // See footnote
// map, flatmap, unit, utility functions
}
val sideEffect = new SideEffect(20)
println(sideEffect.value) // Prints "20"
val stateMonad = State[SideEffect,Int](state => {
state.modifyValue(10)
(state.value,state)
})
stateMonad.run(sideEffect) // run the modification
println(sideEffect.value) // Prints "10" i.e. we have modified the original state
Die einzige Lösung dieses Problems, die ich sehen kann, ist eine Kopie der Klasse zu machen und das ändern, aber das scheint rechnerisch teuer als Nebeneffekt wächst. Und wenn wir etwas wie eine Java-Klasse umhüllen wollten, die Cloneable nicht implementiert, hätten wir kein Glück.
val stateMonad = State[SideEffect,Int](state => {
val newState = SideEffect(state.value) // Easier if it was a case class but hypothetically if one was, say, working with a Java library, one would not have this luxury
newState.modifyValue(10)
(newState.value,newState)
})
stateMonad.run(sideEffect) // run the modification
println(sideEffect.value) // Prints "20", original state not modified
Benutze ich die State-Monade falsch? Wie würde man eine seiteneffektive Klasse umhüllen, ohne sie kopieren zu müssen, oder ist das der einzige Weg?
- Die Umsetzung für den Staat Monade Ich bin hier stammt aus dem Buch mit, und könnte von Scalaz Implementierung