[英]Implementing snapshot in FRP
我在Scala中實現了一個FRP框架,我似乎遇到了一個問題。 在一些思考的啟發下,這個問題我決定限制我的框架的公共接口,所以行為只能在'現在'中進行評估,即:
behaviour.at(now)
這也符合Conal在Fran論文中的假設,即行為只會在不斷增加的時間進行評估/抽樣。 它確實限制了行為的轉換,但是否則我們發現自己遇到了代表一些輸入的行為的巨大問題:
val slider = Stepper(0, sliderChangeEvent)
使用此行為,評估未來值將是不正確的,並且評估過去的值將需要無限量的內存(必須存儲“slider”事件中使用的所有事件)。
鑒於此限制,我在行為上的“快照”操作規范方面遇到了問題。 我的問題最好用一個例子解釋(使用上面提到的滑塊):
val event = mouseB // an event that occurs when the mouse is pressed
val sampler = slider.snapshot(event)
val stepper = Stepper(0, sampler)
我的問題是,如果執行此代碼時發生'mouseB'事件,那么'stepper'的當前值將是'slider'的最后一個'樣本'(最后一次出現時的值)。 如果最后一次出現的時間是過去那么我們將最終使用過去的時間來評估“滑塊”,該時間打破了上面的規則集(以及您的原始假設)。 我可以看到幾種解決方法:
我也可以簡單地不實現'sample'或刪除'stepper'/'switcher'(但我真的不想做這些事情中的任何一個)。 有沒有人對此有任何想法? 我在這里誤解了什么嗎?
從我可以告訴,你擔心的競爭條件:如果在代碼執行時發生的事件會發生什么。
純功能代碼不喜歡必須知道它被執行。 功能技術在純設置中處於最佳狀態,因此執行代碼的順序無關緊要。 擺脫這種困境的一種方法是假裝每一個變化發生在一個敏感的(內部的,可能的)命令式代碼中; 假設FRP框架中的任何功能聲明都發生在0次,因此在聲明期間不可能改變某些內容。
在一段宣稱行為和事物的代碼中,沒有人應該睡覺,或者真正做任何時間敏感的事情。 從本質上講,與FRP對象一起使用的代碼應該是純粹的,那么你就沒有任何問題。
這不一定排除在多個線程上運行它,但為了支持您可能需要重新組織內部表示。 歡迎來到FRP庫實施的世界 - 我懷疑在此過程中您的內部表示會多次波動。 :-)
哦,我明白你的意思了。
我認為,你的“你現在只能'現在'采樣”的限制是不夠緊張的。 它需要更強一些,以避免回顧過去。 既然你正在使用now
的環境概念,我會根據它來定義行為構造函數(只要now
不能通過僅僅執行定義來推進,根據我的上一個答案,它會變得混亂)。 例如:
Stepper(i,e)
是與所述值的行為i
在區間[now,e1]
其中,e1
是第一次出現的時間e
后now
),以及最近出現的值e
之后。
有了這個語義,你對stepper
的價值的預測會讓你陷入這個難題,而步進器現在將具有值0.我不知道這種語義是否適合你,但對我來說似乎很自然。
我對你的困惑感到困惑。 我看到的方式是Stepper
會在事件發生時將行為“設置”為新值。 那么,會發生以下情況:
事件
mouseB
發生的瞬間,將讀取slider
行為的值(snapshot
)。 該值將“設置”到行為stepper
。
因此, Stepper
確實會“記住”過去的價值觀; 關鍵是它只記得過去的最新價值,而不是一切。
從語義上講,最好將Stepper
建模為luqui提出的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.