Ich weiß, dass eine Möglichkeit, dies zu implementieren, darin besteht, den Status jedes Mal neu zu berechnen, wenn eine Änderung eintrifft. Dies scheint jedoch unpraktisch.
Wenn die Änderungen, die beim Eintreten eines Ereignisses angewendet werden, auf die eine oder andere Weise nicht verteilend sind, müssen Sie den Status jedes Mal neu berechnen, wenn ein Ereignis auftritt, da der Endstatus nichts anderes als der Anfangszustand ist, zuzüglich aufeinanderfolgender Änderungen. Und selbst wenn die Änderungen verteilend sind, möchten Sie normalerweise einen Status sukzessive in den nächsten umwandeln, da Sie Ihren Prozess stoppen möchten, sobald ein bestimmter Status erreicht ist, und da Sie den nächsten Status berechnen müssen, um festzustellen, ob der Neu ist der gesuchte Zustand.
Bei der Funktionsprogrammierung werden Zustandsänderungen typischerweise durch Funktionsaufrufe und / oder Funktionsparameter dargestellt.
Da Sie nicht vorhersagen können, wann der Endzustand berechnet wird, sollten Sie keine rekursive Funktion ohne Schwanz verwenden. Ein Strom von Staaten, in denen jeder Staat auf dem vorherigen basiert, könnte eine gute Alternative sein.
In Ihrem Fall würde ich die Frage in Scala mit dem folgenden Code beantworten:
import scala.util.Random
val initState = 0.0
def nextState(state: Double, event: Boolean): Double = if(event) state + 0.3 else state - 0.1 // give a new state
def predicate(state: Double) = state >= 1
// random booleans as events
// nb: must be a function in order to force Random.nextBoolean to be called for each element of the stream
def events(): Stream[Boolean] = Random.nextBoolean #:: events()
val states: Stream[Double] = initState #:: states.zip(events).map({ case (s,e) => nextState(s,e)}) // a stream of all the successive states
// stop when the state is >= 1 ;
// display all the states computed before it stopped
states takeWhile(! predicate(_)) foreach println
Was zum Beispiel geben kann (ich habe die Ausgabe vereinfacht):
0.0
0.3
0.2
0.5
0.8
val states: Stream[Double] = ...
ist die Zeile, in der aufeinanderfolgende Zustände berechnet werden.
Das erste Element dieses Streams ist der Anfangszustand des Systems. zip
führt den Strom von Zuständen mit dem Strom von Ereignissen zu einem einzigen Strom von Paaren von Elementen zusammen, wobei jedes Paar ein (Zustand, Ereignis) ist. map
wandelt jedes Paar in einen einzelnen Wert um, der der neue Zustand ist und als Funktion des alten Zustands und des zugehörigen Ereignisses berechnet wird. Ein neuer Status ist daher ein zuvor berechneter Status sowie das zugehörige Ereignis, das den Status "ändert".
Im Grunde definieren Sie einen potenziell unendlichen Strom von Zuständen, wobei jeder neue Zustand eine Funktion des zuletzt berechneten Zustands und ein neues Ereignis ist. Da Streams in Scala (unter anderem) faul sind, werden sie nur bei Bedarf berechnet, sodass Sie keine nutzlosen Zustände berechnen müssen und so viele Zustände berechnen können, wie Sie möchten.
Wenn Sie nur an dem ersten Status interessiert sind, der das Prädikat berücksichtigt, ersetzen Sie die letzte Codezeile durch:
states find predicate get
Welches ruft ab:
res7: Double = 1.1