haskell - 如何在reactive-banana中处理多个窗口和单个数据结构

标签 haskell reactive-programming reactive-banana

我想知道reactive-banana是如何设计来处理以下情况的:

假设我有一个中央数据结构。用户可以自由打开和关闭任意数量的不同类型的窗口,这些窗口既显示数据,又允许用户修改数据。

因此,考虑到这一点的性质,我认为仅仅尝试创建一个大型网络并不有效。这是每个窗口都有一个网络并且以某种方式连接的东西吗?

在其他类似情况下,我将数据结构放在每个人都向其发送更新的单个 channel 后面。然后数据结构将“发布”所有窗口“监听”的更新(触发事件)。

最佳答案

我在我的一个项目中遇到了一个相关问题,该项目使用类似于 MVC 架构的东西。中心数据结构引用为

-- the data is a tree, and it's kept as a zipper to the current node
Discrete MyDataZip

这是我的 Controller 声明的精简版本:

data Controller st = Controller {
  dState      :: Discrete st
 ,eUpdateZip  :: Event (MyDataZip -> MyDataZip)
 ,eResponse   :: Event (IO ())
 ,bDiagChange :: Behavior (Diagram Cairo R2 -> Diagram Cairo R2)
 }

构建时,大多数 Controller 都会获得对 dZip::Discrete MyDataZip 的引用,但无法直接修改它。 Controller 指定更新的唯一方法是通过 Controller 数据结构中的 eUpdateZip 流。

多个 Controller 被组装成一个图,它只是放置在存在类型包装器中的 Controller 列表data EControl = forall st。 EControl( Controller st)。我只是 mconcat 所有单独的 eUpdateZip 参数来获取单个 Event (MyDataZip -> MyDataZip) 流,该流用于创建 离散MyDataZip。整个事情之所以有效,是因为创建新 Controller 是纯粹的,因此可以在同一个 let 绑定(bind)中完成,从而允许递归引用。

打开新窗口和其他 IO 任务是在 eResponse 流中完成的,它类似于 mconcatd,然后传递给 reactimate

您可以检查darcs repo有关更多详细信息,请查看“src/Jaek/UI/Controllers/”和“src/Jaek/UI/ControlGraph.hs”。

编辑:核心问题是,从开发人员的角度来看,一个大型网络相当笨重。您可以通过对网络进行分段来降低复杂性,这是一个很好的解决方案。在我的设计中,我通过使 react 参与者符合特定的 Controller 模型,并为这些模型创建明确定义的交互方式,向网络引入了许多结构。由于我的 Controller 是持久的,所以都是静态设置的,但它可以动态完成,在这种情况下,我可能会让 Controller 管理器在一个线程中运行,并且生成新 Controller 的操作(例如打开一个新窗口)将发送一个向线程发送消息以创建新 Controller 。

关于haskell - 如何在reactive-banana中处理多个窗口和单个数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7927958/

相关文章:

haskell - 何时使用类型类,何时使用类型

haskell - 我如何轻松地表达我不关心特定数据字段的值?

rx-java - RxJava - 与 switchMap() 运算符相反?

reactive-programming - 流 |处理器和线程模型

ios - Reactive Cocoa 中的可取消超时

haskell - Reactive-Banana 中的动态事件切换

haskell - 如果我需要具有随机访问的数据结构,Vector 是我唯一的不错选择吗?

haskell - Reactive Banana 的 mapAccum 函数是如何工作的?

haskell - 为什么我们要在FRP中使用Behavior