1

为了在 Haskell 中实现可视化的算术表达式编辑器,我定义了以下内容:

data AST = Lit Int
         | Add AST AST
         | Neg AST

eval :: AST -> Int

type TagName = String
type Attrs = M.Map String String
data DOM = Tag TagName Attrs [SubDOM]
data SubDOM = SubNode DOM | Text String

toDOM :: AST -> DOM
fromDOM :: DOM -> AST

我想让用户可以同时编辑 AST 和 DOM,并在它们之间同步用户操作(例如将子节点替换为另一个),此外,我希望有效地同步操作(这意味着只有修改后的子节点应该重建),我应该如何处理这个?

一种解决方案是为每个 AST 节点和 DOM 节点分配一个 id,当一侧发生操作时,我们将此操作同步到具有相同 id 的另一侧节点,但这一步在函数式编程中似乎很棘手,我问了这个问题单独:如何在函数式编程中为 AST 节点生成稳定的 id?.

另一种解决方案是重新定义数据结构,让一侧保留另一侧的IORef,当操作发生时,我们可以通过引用将操作同步到另一侧。但这种方法似乎不起作用。

那么,在函数式编程中是否有解决这个问题的最佳实践?

4

1 回答 1

2

我不确定您是否主要在寻找一种通用的方式来同步两种方式(通过什么界面?这是在浏览器中,还是在纯 Haskell 函数中?),或者是一种做前端的方法网络编程。对于前者,请考虑FRP 和 reactive-banana,它们可以让您表达双向事件。对于后者,考虑类似Miso的东西,它使用 GHCJS 生成与 DOM 有效交互的前端 Web 浏览器代码。(味噌类似于榆树。)

于 2018-06-21T07:12:30.937 回答