Как синхронизировать операции между AST и DOM в haskell?
Чтобы реализовать редактор визуализированных арифметических выражений в 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 идентификатор, и когда операция происходит на одной стороне, мы синхронизируем эту операцию с узлом другой стороны с тем же идентификатором, но этот шаг кажется сложным в функциональном программировании, и я задал этот вопрос отдельно: как генерировать стабильный идентификатор для узлов AST в функциональном программировании?,
Другое решение - переопределить структуру данных, чтобы одна сторона сохраняла IORef другой стороны, и когда операция происходит, мы можем синхронизировать операцию с другой стороной через ссылку. Но этот подход кажется не функциональным.
Итак, есть ли лучший метод решения этой проблемы в функциональном программировании?
1 ответ
Я не уверен, что вы в основном ищете общий способ синхронизации двух вещей в обоих направлениях (через какой интерфейс? Это в браузере или в чистой функции Haskell?) Или для способа выполнения front-end веб-программирование. Для первых рассмотрим FRP и реактивный банан, который позволит вам выражать двунаправленные события. В последнем случае рассмотрим что-то вроде Miso, которое использует GHCJS для создания интерфейсного кода веб-браузера, который эффективно взаимодействует с DOM. (Мисо напоминает Вяза.)