Предположим, что есть некая штука O, что состоит из множества компонентов, включая A и B. Например, такая:
data O = O (Map A B) [F] G
И есть несколько отображений вида:
(A, C) -> O
B -> O
C -> [(B, A) -> O]
Данных немного и хотелось бы их держать в ОЗУ.
Далее, есть ряд операций, что делятся на три категории:
1. добавление O
2. изменение O
3. удаление O с возвратом значения ф-ции f(O)
В каждой из операций указывается некоторая информация для нахождения O и, возможно, работы с ним. В случае проблем любого рода нужно рапортовать об ошибке. Вот пример:
1. Добавить O:
Дано:
A, C, B, O.
Надо добавить O во все отображения. Но:
1. если (A, C) -> _ уже существует -> ошибка №1
2. если B -> _ уже существует -> ошибка №2
3. если C -> (B, A) -> _ уже существует -> ошибка №3
2. Добавить или изменить O:
Дано:
A, C, B, O, f.
Надо добавить O во все отображения. Если оно там уже есть — заменить везде на O' = f(O). Но:
1. если (A, C) -> _ уже существует -> ошибка №1
2. если B -> _ уже существует -> ошибка №2
3. если C -> (B, A) -> _ уже существует -> ошибка №3
4. f(O) тоже может вернуть ошибку
Причем в случае изменения O могут измениться упоминаемые в нем А и B. В таком случае, часть связей из отображений вида * -> O должна пропасть и замениться на новые. Но если они конфликтуют с уже существующими — ошибка № 4.
Думаю, ошибку можно возвращать либо через Either, либо через выбрасывание исключения.
Но вот что делать со всем остальным — не знаю. Как-то муторно писать все это вручную. По духу все эти ограничения и связи напоминают реляционную базу данных, но поднимать для такого MySQL или типа того — overkill. К тому же будет заморочка с сериализацией/десериализацией всех этих A, B, C, O.