如何以优雅的方式"改变"大对象中的单个值?

Vek*_*weg 11 haskell

例如,我有

data ShipDesign = ShipDesign {
      offense :: Offense
    , defense :: Defense
    , maxHealth :: Integer
    , repairRate :: Integer
    , stealth :: Integer
    , radar :: Integer
    , speed :: Integer
    , shipType :: String
    ...
    }
Run Code Online (Sandbox Code Playgroud)

现在我想改变防守.已知的方法是:

changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign
changeDefense fDef sd@(ShipDesign o d m rr s r sp st ...) = ShipDesign o (fDef d) m rr s r sp st ...
Run Code Online (Sandbox Code Playgroud)

这不优雅.特别是在游戏中,每步只更改几个值.

我的问题是:是否有一个库,设计模式或其他方式以更优雅的方式更改单个值?

luq*_*qui 15

是的,您可以使用记录更新表示法:

 changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign
 changeDefense fDef sd = sd { defense = fDef (defense sd) }
Run Code Online (Sandbox Code Playgroud)

但是,当您使用它时,记录更新表示法的局限性将显示出来,并且您将需要更强大的功能.那时,你应该开始了解镜头.