Подтвердить что ты не робот

Нормализованная и неизменная модель данных

Как Haskell решает проблему "нормализованной неизменной структуры данных"?

Например, рассмотрим структуру данных, представляющую бывших подружек/парней:

data Man = Man {name ::String, exes::[Woman]}

data Woman = Woman {name :: String, exes::[Man]}

Что произойдет, если Женщина изменит свое имя, и она была с 13 мужчинами? Тогда весь 13 человек должен быть "обновлен" (в смысле Хаскелла) тоже? Чтобы избежать этих "обновлений", необходима некоторая нормализация.

Это очень простой пример, но представьте себе модель с 20 сущностями и произвольные отношения между ними, что делать дальше?

Каков рекомендуемый способ представления сложных, нормализованных данных на неизменяемом языке?

Например, решение Scala можно найти здесь (см. код ниже) и использует ссылки. Что делать в Haskell?

class RefTo[V](val target: ModelRO[V], val updated: V => AnyRef) {
  def apply() = target()
}

Интересно, если в Haskell не работают более общие решения, такие как выше (в Scala), или они не нужны? Если они не работают, то почему бы и нет? Я попытался найти библиотеки, которые делают это в Haskell, но они, похоже, не существуют.

Другими словами, если я хочу моделировать нормализованную базу данных SQL в Haskell (например, для использования с acid-state), существует общий способ описания внешних ключей? Под общим я имею в виду, а не вручную кодирование идентификаторов, как предложено chepner в комментариях ниже.

EDIT:

Иными словами, существует ли библиотека (для Haskell или Scala), которая реализует SQL/реляционную базу данных в памяти (возможно, также используя Event Sourcing for persistence), так что база данных является неизменной и большинство операций SQL (query/join/insert/delete/etc.) реализованы и безопасны по типу? Если такой библиотеки нет, почему бы и нет? Кажется, это довольно хорошая идея. Как создать такую ​​библиотеку?

ИЗМЕНИТЬ 2:

Некоторые связанные ссылки:

4b9b3361

Ответ 1

Проблема заключается в том, что вы храните данные и отношения одного типа. Чтобы нормализовать, вам нужно отделить. Реляционные базы данных 101.

newtype Id a = Id Int -- Type-safe ID.
data Person = Person { id :: Id Person, name :: String }
data Ex = Ex { personId :: Id Person, exId :: Id Person }

Теперь, если человек меняет свое имя, влияет только одно значение Person. Записи Ex не заботятся о именах людей.