Обновление записи при ссылке на несколько структур данных

Предположим, у меня есть запись, например,Personи я хочу иметь возможность искать этого человека через несколько структур данных. Может быть, есть индекс по имени, другой индекс по почтовому индексу человека и другой индекс по текущей широте и долготе человека. И, может быть, еще много структур данных. Все это существует, потому что мне нужно эффективно искать человека или людей с другими критериями.

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

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

Итак, как это можно сделать на Haskell? Чтобы было ясно, проблема заключается в следующем: я ищу человека по одной структуре данных, и я передаю этого человека (и, возможно, некоторые другие произвольные данные) в функцию типаArbitraryData -> Person -> Person, Как мне распространить это изменение по всем различным структурам поиска?

Как относительный новичок в Haskell, мой первый инстинкт - реконструировать каждую структуру поиска с недавно обновленным человеком, каждый раз, когда я обновляю человека. Но это кажется большой церемонией, с большим количеством возможностей для меня, чтобы испортить путь, который GHC не может обнаружить, и вовсе не элегантно. Haskell известен своей элегантностью, и я не могу себе представить, что ему не хватает элегантного решения такой распространенной и основной проблемы. Так что я думаю, что что-то упустил.

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

Несколько структур поиска для одних и тех же данных: дублирование памяти?

Идентичность объектов симуляции в Haskell

редактировать

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

Я не знаю, будет ли это эффективно. Если это приводит к тому, что ЦП фактически пересчитывает структуру поиска при каждом использовании, это недопустимо. Но я знаю, что Хаскелл иногда может избежать переоценки идентичных выражений. К сожалению, я до сих пор не понялкогда В этом случае. Так что я не знаю, является ли этот подход жизнеспособным.

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