Tôi biết rằng một cách để thực hiện điều này là tính toán lại trạng thái mỗi khi có thay đổi, tuy nhiên điều này có vẻ không thực tế.
Nếu các thay đổi được áp dụng khi một sự kiện xảy ra không phải là phân phối, bằng cách này hay cách khác, bạn sẽ phải tính toán lại trạng thái mỗi khi một sự kiện xảy ra, vì trạng thái cuối cùng không là gì ngoài trạng thái ban đầu, cộng với các thay đổi liên tiếp. Và ngay cả khi các thay đổi có tính phân phối, bạn thường muốn chuyển đổi liên tục trạng thái sang trạng thái tiếp theo, vì bạn muốn dừng quá trình của mình nhanh nhất khi đạt đến trạng thái nhất định và vì bạn phải tính toán trạng thái tiếp theo để xác định xem cái mới là trạng thái mong muốn.
Trong lập trình chức năng, các thay đổi trạng thái thường được biểu thị bằng các lệnh gọi hàm và / hoặc tham số hàm.
Vì bạn không thể dự đoán khi nào trạng thái cuối cùng sẽ được tính toán, bạn không nên sử dụng hàm đệ quy không đuôi. Một luồng các trạng thái, trong đó mỗi trạng thái dựa trên trạng thái trước đó, có thể là một lựa chọn tốt.
Vì vậy, trong trường hợp của bạn, tôi sẽ trả lời câu hỏi theo đoạn mã sau, trong Scala:
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
Chẳng hạn, có thể đưa ra (tôi đã đơn giản hóa đầu ra):
0.0
0.3
0.2
0.5
0.8
val states: Stream[Double] = ...
là dòng nơi các trạng thái liên tiếp được tính toán.
Phần tử đầu tiên của luồng này là trạng thái ban đầu của hệ thống. zip
hợp nhất luồng trạng thái với luồng sự kiện thành một luồng các cặp yếu tố, mỗi cặp là một (trạng thái, sự kiện). map
biến đổi mỗi cặp thành một giá trị duy nhất là trạng thái mới, được tính là một hàm của trạng thái cũ và sự kiện liên quan. Do đó, một trạng thái mới là trạng thái được tính toán trước đó, cộng với sự kiện liên quan "sửa đổi" trạng thái.
Về cơ bản, bạn xác định một luồng trạng thái có khả năng vô hạn, mỗi trạng thái mới là một hàm của trạng thái được tính toán cuối cùng và một sự kiện mới. Vì các luồng lười biếng trong Scala (trong số các luồng khác), chỉ có tính toán theo yêu cầu, do đó bạn không phải tính toán các trạng thái vô dụng và bạn có thể tính toán bao nhiêu trạng thái như bạn muốn.
Nếu bạn chỉ quan tâm đến trạng thái đầu tiên tôn trọng vị ngữ, hãy thay thế dòng mã cuối cùng bằng:
states find predicate get
Mà lấy:
res7: Double = 1.1