Bunu uygulamanın bir yolunun her değişiklik geldiğinde durumu yeniden hesaplamak olduğunu biliyorum, ancak bu pratik görünmüyor.
Bir olay meydana geldiğinde uygulanan değişiklikler dağıtıcı değilse, şu ya da bu şekilde, her olay gerçekleştiğinde durumu yeniden hesaplamanız gerekir, çünkü son durum başlangıç durumundan başka ardışık değişikliklerden başka bir şey değildir. Değişiklikler dağıtıcı olsa bile, genellikle belirli bir duruma bir sonraki duruma bir geçiş yapmak istersiniz, çünkü işleminizi belirli bir duruma ulaştığınız anda durdurmak istediğinizden ve bir sonraki durumu hesaplamak zorunda olduğunuzdan emin olun. yenisi aranan devlettir.
Fonksiyonel programlamada, durum değişiklikleri tipik olarak fonksiyon çağrıları ve / veya fonksiyon parametreleri ile temsil edilir.
Son durumun ne zaman hesaplanacağını tahmin edemeyeceğiniz için, kuyruk olmayan özyinelemeli işlev kullanmamalısınız. Her bir devletin öncekine dayandığı bir devlet akışı iyi bir alternatif olabilir.
Yani sizin durumunuzda, soruyu Scala'da aşağıdaki kodla cevaplayacağım:
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
Hangi verebilir, örneğin (Ben çıktı basitleştirilmiş):
0.0
0.3
0.2
0.5
0.8
val states: Stream[Double] = ...
ardışık durumların hesaplandığı satırdır.
Bu akışın ilk elemanı sistemin başlangıç durumudur. zip
durum akışını olay akışıyla tek bir çift öğe akışında birleştirir, her çift bir (durum, olay) olur. map
her çifti, eski durumun ve ilişkili olayın fonksiyonu olarak hesaplanan yeni durum olan tek bir değere dönüştürür. Bu nedenle, yeni bir durum önceden hesaplanmış bir durumun yanı sıra durumu "değiştiren" ilişkili olaydır.
Temel olarak, potansiyel olarak sonsuz bir durum akışı tanımlarsınız, her yeni durum son hesaplanan durumun bir fonksiyonu ve yeni bir olaydır. Scala'da (diğerlerinin yanı sıra) akışlar tembel olduğu için sadece talep üzerine hesaplanır, bu nedenle işe yaramaz durumları hesaplamak zorunda değilsiniz ve istediğiniz kadar eyaleti hesaplayabilirsiniz.
Yalnızca yüklemlere uyan ilk durumla ilgileniyorsanız, son kod satırını şu şekilde değiştirin:
states find predicate get
Hangi alır:
res7: Double = 1.1