簡體   English   中英

功能反應式編程的“信號”表示是否正確?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM