How can I generalize non-trivial record updates? Here is simple example that explicitly updates item references to their new owner.
data Owner = Owner {
items :: [Item]
} deriving (Show)
data Item = Item {
name :: String,
owner :: Owner
}
instance Show Item where
show (Item name _) = name
item1 = Item "a" owner1
item2 = Item "b" owner1
item3 = Item "c" owner1
owner1 = Owner [item1,item2,item3,Item "d" owner1]
owner2 = Owner $ map (\(Item n o) -> Item n owner2) $ items owner1
Note that in Haskell values are immutable, so you can't change the value of owner1
or item1
.
I think the data structure you are looking for is Map OwnerId [Item]
- i.e. a map whose keys are some owner id (a String
or Int
) and whose values are lists of items (the items owned by the owner):
type OwnerId = Int -- or String
data Item = Item { owner :: OwnerId, name :: String }
type WhoOwnsWhat = Map OwnerId [Item]
When you change the owner of an item you are really creating a new map by updating the two map entries with the new list of items. To reassign an item you specify the current map of who owns what, the item and the new owner and get back a new map of who owns what:
changeOwner :: WhoOwnsWhat -> Item -> OwnerId -> WhoOwnsWhat
Adding a new item involves a function like:
addItem :: WhoOwnsWhat -> Item -> WhoOwnsWhat
Note that in each case we are creating a new map.