Suppose I have a record, e.g. Person
, and I want to be able to look this person up through multiple data structures. Maybe there\'s an index by name, another in
Since I answered this, a few people in #haskell on Freenode recommended alternative, premade solutions:
You can make a data structure that contains your lookup tables, as well as a Vector of actual Person
s. The lookup tables will give you an Int
or a list of Int
s (rather than a Person
or a list of Person
s) which is the index into the Vector Person
. For example:
data PersonStuff = PersonStuff {
persons :: Vector Person,
firstNameLookupTable :: LookupTable Name,
...
}
data LookupTable a = LookupTable {
table :: Map a Int,
update :: Person -> Person -> Map a Int -> Map a Int
}
The update
function is given the old Person
, the updated Person
, and will update the table only if the relevant details have changed. When a Person
is modified through the convenient PersonStuff
functions you'll write, those functions will update all the lookup tables for you, returning a new PersonStuff
with all associated data. This makes for a pure data structure with quick lookups.
You can make functions like updatePeopleWithFirstName :: Name -> (Person -> Person) -> PersonStuff -> PersonStuff
that will get all the people with a first name, apply a Person -> Person
to each of them, modify their entries in the Vector
, and use the update
functions to update all of the lookupTables.