Как 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:
Некоторые связанные ссылки:
- https://realm.io/news/slug-peter-livesey-managing-consistency-immutable-models/
- https://tonyhb.gitbooks.io/redux-without-profanity/content/normalizer.html
- https://github.com/agentm/project-m36
- https://github.com/scalapenos/stamina
- http://www.haskellforall.com/2014/12/a-very-general-api-for-relational-joins.html