Pau*_*son 8 haskell zipper data-structures
我正在为"模型"编写一个图形编辑器(即带有某种语义的框和行的集合,例如UML,其细节在这里无关紧要).所以我希望有一个表示模型的数据结构,以及一个图表,其中对图表的编辑会导致模型中的相应更改.因此,例如,如果模型元素在属性中有一些文本,并且我编辑图中的文本,我希望更新模型元素.
该模型可能会表示为树,但我希望图表编辑器尽可能少地了解模型表示.(我正在使用图表框架,因此将任意信息与图形元素相关联很容易).如果我能弄清楚应该是什么,可能会有一个"模型"类来编码接口.
如果我用命令式语言执行此操作,那将很简单:我只需要从图中的图形元素返回到模型元素.从理论上讲,我仍然可以通过从大量的IORef集合中构建模型来实现这一点,但那将是在Haskell中编写Java程序.
显然,每个图形元素都会有一些与之关联的cookie,这样就可以实现模型更新.一个简单的答案是为每个模型元素提供唯一标识符,并将模型存储在Data.Map查找表中.但这需要大量的簿记才能确保没有两个模型元素获得相同的标识符.这也是一种"串型"解决方案; 你必须处理一个对象被删除的情况,但是在其他地方有一个悬挂的引用,并且很难对你的类型中的模型的内部结构说些什么.
另一方面,奥列格的关于具有多个孔和光标的拉链以及清晰的交易共享的着作听起来像是一个更好的选择,只要我能理解它.我得到了列表和树拉链的基本概念以及数据结构的区别.图表中的每个元素都可以将光标保存到模型的拉链中吗?那么如果进行了更改,则可以将其提交给所有其他游标?包括树操作(例如将子树从一个地方移动到另一个地方)?
如果有一些关于分隔延续的教程,以及它们如何使Oleg的多光标拉链工作,这比Oleg的帖子稍微陡峭一点,那对我来说尤其有帮助吗?
我认为您当前正在进行的设计中,模型树中的每个节点都由单独的图形小部件表示,并且每个小部件都可以独立更新模型。如果是这样,我不相信多孔拉链会很实用。问题在于,拉链的复杂性随着您希望支撑的孔的数量而迅速增加。当超过 2 个术语时,拉链的尺寸将变得相当大。从差异化的角度来看,2孔拉链是优于1孔拉链的拉链,因此链式法则的操作会增加复杂性。
相反,您可以借用 MVC 的想法。每个节点仍然与一个小部件关联,但它们不直接通信。相反,它们通过一个中间控制器,该控制器维护一个拉链。当小部件更新时,它们会通知控制器,控制器会序列化所有更新并相应地修改拉链。
小部件仍然需要某种标识符来引用模型节点。我发现使用节点的路径通常是最简单的,例如[0]
对于根节点、[1,0]
对于根节点的第二个子节点等。这有一些优点。很容易确定路径所引用的节点,并且拉链也很容易计算从当前位置到给定节点的最短路径。对于树结构,它们在删除和重新插入方面也是唯一的。即使这通常也不是问题,因为当控制器收到应删除节点的通知时,它可以删除相应的小部件并忽略任何关联的更新。只要小部件的生命周期与每个节点的生命周期相关,该路径就足够唯一以识别任何修改。
对于树操作,我可能会销毁然后重新创建图形小部件。
作为一个例子,我有一些代码可以完成这类事情。在此模型中,每个节点没有单独的小部件,而是使用图表渲染所有内容,然后根据单击位置查询图表以获取数据模型的路径。它还远未完成,而且我已经有一段时间没有查看它了,所以它可能无法构建,但代码可能会给您一些想法。