1

To implement a visualized arithmetic expression editor in Haskell, I defined the following things:

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

I want to make it possible for user to edit both the AST and the DOM, and sync the user operations (such as substitute a child node into another) between them, and further more, I want to sync operations efficiently (which means only the modified child node should be reconstructed), how should I approach this?

One solution is allocate each AST node and DOM node an id, and when an operation happens on one side, we sync this operation to the other side node with the same id, but this step seem tricky in functional programming, and I asked this question separatly: How to generate stable id for AST nodes in functional programming? .

Another solution is redefine the data structure, so that one side keep an IORef of the other side, and when an operation happens, we can sync the operation to the other side via the reference. But this approach seems not functional.

So, is there a best practice for this problem in functional programming?

luochen1990
  • 3,689
  • 1
  • 22
  • 37

1 Answers1

2

I'm not sure if you're mainly looking for a general way to synchronise two things both ways (across what interface? Is this in a browser, or in a pure Haskell function?), or for a way to do front-end web programming. For the former, consider FRP and reactive-banana which will let you express bi-directional events. For the latter, consider something like Miso which uses GHCJS to produce front-end web-browser code that interacts efficiently with the DOM. (Miso resembles Elm.)

sshine
  • 15,635
  • 1
  • 41
  • 66
  • Sorry for the unclear, Now I added more description trying to make it more clear. – luochen1990 Jun 21 '18 at 15:39
  • @luochen1990: I'm not sure what else to say. You could read [how Miso does it](https://github.com/dmjio/miso/blob/master/ghcjs-src/Miso/Html/Internal.hs) using GHCJS. – sshine Jun 22 '18 at 08:16