Frage

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
War es hilfreich?

Lösung

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top