[英]Is the 'Signal' representation of Functional Reactive Programming correct?
我一直在研究FRP,發現了一堆不同的實現。 我見過的一個模型是我將其稱為“信號”表示的模型。 這一基本要素將事件和行為結合到一個實體中。
首先,Signal是一個值為行為的對象。 其次,信號有一個事件'流',可以作為標准數據結構查看和操作(您可以在信號上使用'each','map'和'filter'等來定義事件如何反應)。 例如,我可以這樣做(其中'時間'是時間的信號表示):
time.each { t => print(t) } // every time there is a 'tick' the current time is printed
a = time * 5 //where 'a' would be a dynamic value always up to date with time
FRP的這種表示是正確的還是有問題? 我非常喜歡它的工作方式以及個人描述的簡單方法,但我不確定它的正確性。
不幸的是,將“事件”和“行為”合並為單個實體“信號”並不能很好地工作。
我所知道的大多數基於信號的FRP實現最終會創建一個類似於“事件”的附加類型
type Event a = Signal (Maybe a)
因此,事件的概念不會消失,也沒有真正的簡化。 事實上,我認為信號類型是語義合並。 信號很受歡迎,因為它們更容易實現。
反對信號的主要論據是它們不能代表連續的時間行為,因為它們必須迎合離散事件。 在Conal Elliott 最初的願景中 ,行為是簡單的連續時間函數
type Behavior a = Time -> a
-- = function that takes the current time as parameter and returns
-- the corresponding value of type a
相反,信號始終是離散的,並且通常與固定的時間步長相關聯。 (可以在可變時間步長信號的基礎上實現事件和行為,但它本身並不是一個好的抽象。)將此與事件流進行比較
type Event a = [(Time,a)]
-- list of pairs of the form (current time, corresponding event value)
其中個別事件不一定以規則間隔的時間間隔發生。
行為和事件之間區別的論點是它們的API非常不同。 重點是他們有不同的產品類型:
(Behavior a , Behavior b) = Behavior (a,b)
(Event a , Event b ) = Event (a :+: b)
用語言來說:一對行為與對的行為相同,但是一對事件與來自任一組件/通道的事件相同。 另一點是有兩個操作
(<*>) :: Behavior (a -> b) -> Behavior a -> Behavior b
apply :: Behavior (a -> b) -> Event a -> Event b
它們具有幾乎相同的類型,但語義卻截然不同。 (第一個參數更改時,第一個更新結果,而第二個參數更改時,第一個更新結果。)
總結一下:信號可用於實現FRP,對於嘗試新的實現技術很有價值,但對於只想使用FRP的人來說,行為和事件是更好的抽象。
(完全披露:我在Haskell中實現了一個名為reactive-banana的FRP庫。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.