假设我有以下数据模型,用于跟踪棒球运动员,球队和教练的统计信息:
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中有一个针对此问题(或类似问题?)的东西: update-in-因此,我认为我试图update-in在函数式编程,Haskell和静态类型化的上下文中进行理解。
波斯汪
素胚勾勒不出你