Есть ли Haskell Idiom для обновления вложенной структуры данных?

Допустим, у меня есть следующие модели данных, для отслеживания статистики бейсболистов, команд и тренеров:

data BBTeam = BBTeam { teamname :: String, 
                       manager :: Coach,
                       players :: [BBPlayer] }  
     deriving (Show)

data Coach = Coach { coachname :: String, 
                     favcussword :: String,
                     diet :: Diet }  
     deriving (Show)

data Diet = Diet { dietname :: String, 
                   steaks :: Integer, 
                   eggs :: Integer }  
     deriving (Show)

data BBPlayer = BBPlayer { playername :: String, 
                           hits :: Integer,
                           era :: Double }  
     deriving (Show)

теперь скажем, что менеджеры, которые обычно стейки фанатики, хотят есть еще больше Стейк - поэтому мы должны быть в состоянии увеличить содержание стейка в диете менеджера. Вот две возможные реализации для этой функции:

1) Это использует много сопоставления шаблонов, и я должен получить все инструкции, заказывающие для всех конструкторов прямо ... дважды. Похоже, это не будет масштабироваться очень хорошо или быть очень ремонтом / читаемым.

addManagerSteak :: BBTeam -> BBTeam
addManagerSteak (BBTeam tname (Coach cname cuss (Diet dname oldsteaks oldeggs)) players) = BBTeam tname newcoach players
  where
    newcoach = Coach cname cuss (Diet dname (oldsteaks + 1) oldeggs)

2) Это использует все доступности, предоставленные синтаксисом записи HASKELL, но это также уродливая и повторяется, и трудно поддерживать и читать, я думаю.

addManStk :: BBTeam -> BBTeam
addManStk team = newteam
  where
    newteam = BBTeam (teamname team) newmanager (players team)
    newmanager = Coach (coachname oldcoach) (favcussword oldcoach) newdiet
    oldcoach = manager team
    newdiet = Diet (dietname olddiet) (oldsteaks + 1) (eggs olddiet)
    olddiet = diet oldcoach
    oldsteaks = steaks olddiet

Мой вопрос в том, является одним из них лучше другого или более предпочтительнее в сообществе Haskell? Есть ли лучший способ сделать это (для модификации значения глубоко внутри структуры данных при сохранении контекста)? Я не беспокоюсь о эффективности, просто код элегантности / общности / ремонтопригодности.

Я заметил, что есть что-то для этой проблемы (или подобная проблема?) В Clojure: Обновление - поэтому я думаю, что я пытаюсь понять ] В контексте функционального программирования и Haskell и Staticys.

42
задан amindfv 24 December 2011 в 07:47
поделиться