gpt4 book ai didi

haskell - FRP - 事件流和信号 - 仅使用信号会丢失什么?

转载 作者:行者123 更新时间:2023-12-03 11:35:31 25 4
gpt4 key购买 nike

在经典 FRP 的最新实现中,例如 react 香蕉,有事件流和信号,它们是阶跃函数( react 香蕉称它们为行为,但它们仍然是阶跃函数)。我注意到 Elm 只使用信号,并没有区分信号和事件流。此外,reactive-banana 允许从事件流到信号(已编辑:虽然它不被认为是好的做法,但可以使用 reactimate 对行为采取行动),这意味着理论上我们可以应用所有事件流通过首先将信号转换为事件流,应用然后再次转换来对信号/行为进行组合器。那么,考虑到它通常更容易使用和学习一个抽象,分离信号和事件流有什么好处?仅使用信号并将所有事件流组合器转换为对信号进行操作是否会丢失任何东西?

编辑:讨论非常有趣。我自己从讨论中得出的主要结论是,相互递归定义(反馈)和输出依赖于两个输入(一个行为和一个事件源)都需要行为/事件源,但只有在一个输入时才会导致 Action 其中有变化 (<@>)。

最佳答案

(澄清:在 react 香蕉中,不可能将 Behavior 转换回 Eventstepper 函数是单程票。有一个 changes 函数,但它的类型表明它是“不纯的”,并带有一个警告,即它不保留语义。)

我相信拥有两个独立的概念会使 API 更加优雅。换句话说,它归结为 API 可用性的问题。我认为这两个概念的行为完全不同,如果你有两种不同的类型,事情就会变得更好。

例如,直销产品对于每种类型是不同的。一对 Behavior 等价于一对 Behavior

(Behavior a, Behavior b) ~ Behavior (a,b)

而一对事件等价于直接和的事件:
(Event    a, Event    b) ~ Event (EitherOrBoth a b)

如果将这两种类型合并为一种,那么这些等价性将不再成立。

但是,将Event和Behavior分开的主要原因之一是后者做了 不是 的概念变化或“更新”。起初这似乎是一个遗漏,但在实践中它非常有用,因为它导致代码更简单。例如,考虑一个单子(monad)函数 newInput创建一个输入 GUI 小部件,该小部件显示参数 Behavior 中指示的文本,
input <- newInput (bText :: Behavior String)

现在的关键点是显示的文本不取决于行为 bText 的频率。可能已更新(更新为相同或不同的值),仅针对实际值本身。这比另一种情况更容易推理,在这种情况下,您必须考虑当两个连续事件发生具有相同值时会发生什么。您是否在用户编辑文本时重绘文本?

(当然,为了实际绘制文本,库必须与 GUI 框架交互并跟踪 Behavior 的变化。这就是 changes 组合器的用途。但是,这可以看作是优化,不能从“FRP 内”获得。)

分开的另一个主要原因是 递归 .大多数递归地依赖于自身的事件是不明确的。但是,如果事件和行为之间存在相互递归,则始终允许递归
e = ((+) <$> b) <@> einput
b = stepper 0 e

无需手动引入延迟,它开箱即用。

关于haskell - FRP - 事件流和信号 - 仅使用信号会丢失什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22989253/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com