繁体   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