函数响应式编程的“信号”表示是不是正确?

Posted

技术标签:

【中文标题】函数响应式编程的“信号”表示是不是正确?【英文标题】:Is the 'Signal' representation of Functional Reactive Programming correct?函数响应式编程的“信号”表示是否正确? 【发布时间】:2011-11-19 01:28:45 【问题描述】:

我一直在研究 FRP,发现了一堆不同的实现。我见过的一种模型是我将其称为“信号”表示的模型。这一基本要素将事件和行为组合到一个实体中。

首先,信号是一个对象,它的值是一个行为。其次,信号有一个事件“流”,可以作为标准数据结构查看和操作(您可以在信号上使用“每个”、“映射”和“过滤器”等来定义事件的反应方式)。例如我可以这样做(其中“时间”是时间的信号表示):

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 的这种表示是否正确或有任何问题?我非常喜欢它的工作方式,以及个人描述的简单程度,但我不确定它是否正确。

【问题讨论】:

【参考方案1】:

不幸的是,将“事件”和“行为”合并为单个实体“信号”效果不佳。

我知道的大多数基于信号的 FRP 实现最终都会创建一个额外的类似“事件”的类型

type Event a = Signal (Maybe a)

因此,事件的概念并没有消失,也没有真正的简化。事实上,我认为信号类型是语义上的复杂化。信号之所以受欢迎,只是因为它们更容易实现。

反对信号的主要论点是它们不能代表连续的时间行为,因为它们必须迎合离散事件。在 Conal Elliott 的 original vision 中,行为是时间的简单连续函数

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 库。)

【讨论】:

因此,与其将“时间”作为行为和事件,不如将“时间”作为行为,将“时钟”作为完全独立的事件流?跨度> @Oetzi:啊,我使用的是 Haskell 表示法。我的意思是Behavior a是一个从时间(Time)到a类型值的函数,即它只是一个以当前时间为参数并返回相应值的函数。相反,事件流将是事件发生的列表。没有明确的方法可以将两者统一为某种“信号”概念,因为行为可能类似于example_behavior(time) = 2*time 是的,这是有道理的。我正在为我的论文实现 FRP,我想我可能会使用纯行为和事件,然后也使用它们实现信号 - 只是为了比较。非常感谢您的帮助! Elm 只有信号,没有事件/行为,你怎么看? @CMCDragonkai Elm 的Signal 类型是EventBehavior 的混合。我认为使用不同的类型会更清楚,但我没有使用 Elm 来确定具体的例子。

以上是关于函数响应式编程的“信号”表示是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章

函数响应式编程(FRP)思想

Reactor响应式编程(FluxMono)基本用法

函数响应式编程(FRP)思想-Callback风格

响应式编程 函数式编程 简介

前几天有个同学问我,“什么是响应式编程”?另,它和函数式编程有啥区别?

Swift 响应式编程