Aktualizowanie rekordu, do którego odwołuje się wiele struktur danych

Załóżmy, że mam rekord, np.Personi chcę być w stanie spojrzeć na tę osobę przez wiele struktur danych. Może jest indeks według nazwy, inny indeks według kodu pocztowego osoby i inny indeks według bieżącej szerokości i długości geograficznej osoby. I może wiele innych struktur danych. Wszystko to istnieje, ponieważ muszę sprawnie szukać osoby lub osób o różnych kryteriach.

Jeśli tylko muszęczytać atrybuty osoby,to nie jest problem. Ale teraz załóżmy, że muszę znaleźć osobę korzystającą z jednej z tych struktur danych, a następnieaktualizacja dane osoby.

W języku OOP każda struktura danych wskazywałaby na tę samą osobę w pamięci. Więc kiedy aktualizujesz jeden, niejawnie aktualizujesz również odnośniki innych struktur danych. Jest to w dużej mierze definicja skutków ubocznych i zanieczyszczenia. Wiem, że jest to całkowicie sprzeczne z paradygmatem Haskella i nie oczekuję, że Haskell będzie działał w ten sposób.

Więc jaki jest sposób Haskella? Żeby było jasne, problem polega na tym: szukam osoby przez jedną strukturę danych i przekazuję tę osobę (a może jakieś inne dowolne dane) do funkcji typuArbitraryData -> Person -> Person. Jak propagować tę zmianę we wszystkich różnych strukturach wyszukiwania?

Jako względny nowicjusz Haskella, moim pierwszym instynktem jest odtworzenie każdej struktury wyszukiwania za pomocą nowo zaktualizowanej osoby, za każdym razem, gdy aktualizuję osobę. Ale wydaje mi się, że to dużo ceremonii, z dużą ilością okazji, by zepsuć się w sposób, którego GHC nie może wykryć, i wcale nie jest elegancki. Haskell jest znany ze swojej elegancji i nie wyobrażam sobie, że brakuje mu eleganckiego rozwiązania tak powszechnego i podstawowego problemu. Więc myślę, że coś mi brakuje.

Dla odniesienia, to pytanie rozszerza niektóre kwestie, o których dyskutowałem w następujących pytaniach:

Wiele struktur wyszukiwania dla tych samych danych: powielanie pamięci?

Tożsamość obiektów symulacyjnych w Haskell

Edytować

Jedno rozwiązanie, które właśnie przyszło mi do głowy: nie przechowuj kopii każdej struktury wyszukiwania w głównym stanie. Po prostu zachowaj jedną listę wszystkich istniejących osób, a to jest jedyna rzecz, którą musimy zaktualizować, gdy aktualizujemy osobę. Za każdym razem, gdy musisz wyszukać, powiedzmy, kod pocztowy, przekaż listę wszystkich osób do funkcji, która generuje efektywną strukturę danych kodu pocztowego. Następnie wykonaj wyszukiwanie wyniku.

Nie wiem, czy byłoby to skuteczne. Jeśli powoduje to, że procesor faktycznie przelicza strukturę wyszukiwania przy każdym użyciu, jest to niedopuszczalne. Ale wiem, że czasami Haskell może uniknąć ponownej oceny identycznych wyrażeń. Niestety, wciąż się nie domyśliłemgdy tak jest w przypadku. Więc nie wiem, czy to podejście jest opłacalne.

Innymi słowy: Czy mogę napisać swoje funkcjejak gdyby obliczają wyszukiwanie za każdym razem, gdy w rzeczywistości GHC zoptymalizuje go w przypadkach, w których dane nie uległy zmianie? Ponieważ byłoby tobardzo eleganckie rozwiązanie problemu, który zidentyfikowałem powyżej.

questionAnswers(7)

yourAnswerToTheQuestion