Какую структуру данных выбрать для универсальности, но безопасности? - PullRequest
4 голосов
/ 11 мая 2011

Скажите, у меня есть длинное определение структуры данных

data A = A {
  x1 :: String
, x2 :: String
...
, x50 :: String
}

Теперь у меня есть 3 задачи:

  1. создать черновой экземпляр A как A {x1 = "это x1", ...}
  2. создать экземпляр A из некоторой другой структуры данных
  3. создать другой экземпляр данных из экземпляра A

Три задачи включаютутомительное копирование меток x1, ..., x50.Лучшим решением будет общий список

[
  Foo "x1" aValue1
, Foo "x2" aValue2
...
]

, поскольку это значительно облегчит обход и создание черновика (определение списка уже является черновиком).Недостатком является то, что сопоставление других структур данных с этим было бы более опасным, поскольку вы теряете статическую проверку типов.

Имеет ли это смысл?Есть ли общее, но безопасное решение?

Редактировать : Чтобы дать вам лучшее представление, речь идет о сопоставлении бизнес-данных с текстовым представлением, таким как формы и буквы.Например:

data TaxData = TaxData {
  taxId :: String
, income :: Money
, taxPayed :: Money,
, isMarried :: Bool
...
}


data TaxFormA = TaxFormA {
  taxId :: Text
, isMarried :: Text
  ...
}
data TaxFormB = TaxFormB {
  taxId :: Text
, taxPayedRounded :: Text
...
}

Они преобразуются в поток текста, представляющего фактические формы.Если бы я создал форму из налоговых данных за один проход, а в следующем году любое поле формы было бы перемещено, то, например, было бы отклонение «0.0», и я бы не знал, где оно принадлежит.Для этого и предназначена промежуточная база данных: она позволяет легко создавать черновые данные.

Поэтому мне необходимо сопоставить фактические данные TaxData с этими данными промежуточной формы;мне нужно сопоставить эти данные формы с фактическим текстовым представлением формы;мне нужно создать черновик промежуточной формы данных.С одной стороны, я ненавижу повторять эти метки данных, с другой стороны, это дает мне безопасность, так что я не путаю метки при отображении.Есть ли серебряная пуля?

1 Ответ

3 голосов
/ 11 мая 2011

Подобные глубоко структурированные данные наиболее идиоматически выражаются в Haskell как вложенные алгебраические типы данных, как вы это и сделали. Зачем? Это обеспечивает большую структуру типов и безопасность данных, не позволяя функциям переводить данные в неправильный формат. Дополнительную безопасность можно получить, если ввести новые типы некоторых типов, чтобы увеличить различия между данными в каждом поле.

Тем не менее, очень большие ADT, такие как это, могут быть громоздкими для имени и манипулирования. Типичная ситуация в дизайне компилятора - например, указание такого большого ADT, и чтобы помочь написать код для компилятора, мы склонны использовать множество общих приемов программирования: SYB, метапрограммирование, даже Template Haskell, чтобы генерировать все шаблон нам нужен.

Итак, в целом, я бы придерживался подхода ADT, который вы используете, но остановился на использовании обобщений (например, SYB или Template Haskell) для генерации некоторых ваших определений и вспомогательных функций.

...