Disons que j'ai les données suivantes modèle, pour garder la trace des statistiques de baseball, les joueurs, les équipes et les entraîneurs:
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)
Maintenant, disons que les gestionnaires, qui sont généralement bifteck de fanatiques, envie de manger encore plus de steak -- nous devons donc être en mesure d'augmenter le steak contenu d'un gestionnaire de l'alimentation. Voici deux implémentations possibles pour cette fonction:
1) Il utilise beaucoup de pattern matching et je dois l'obtenir tout de l'argument de la commande pour tous les constructeurs de droite ... deux fois. Il me semble qu'il ne serait pas très bien ou très maintenable/lisible.
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) il utilise tous les accesseurs fournis par Haskell record de la syntaxe, mais c'est aussi moche et répétitif et difficile à maintenir et à lire, je pense.
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
Ma question est, est l'un de ces meilleurs que les autres, ou plus préféré dans le Haskell communauté? Est-il une meilleure façon de le faire (pour modifier une valeur de profondeur à l'intérieur d'une structure de données tout en gardant le contexte)? Je ne suis pas inquiet à propos de l'efficacité, du code de l'élégance/généralité/maintenabilité.
J'ai remarqué il y a quelque chose pour ce problème (ou un problème similaire?) en Clojure: update-in
-- donc, je pense que j'essaie de comprendre update-in
dans le cadre de la programmation fonctionnelle et Haskell et le typage statique.