2013-07-08 1 views
11

は例えば、私は大きなオブジェクトの単一の値をエレガントな方法で「変更」する方法は?

data ShipDesign = ShipDesign { 
     offense :: Offense 
    , defense :: Defense 
    , maxHealth :: Integer 
    , repairRate :: Integer 
    , stealth :: Integer 
    , radar :: Integer 
    , speed :: Integer 
    , shipType :: String 
    ... 
    } 

は、今私は防衛を変更する必要があります。 これを行うには、既知の方法は次のとおりです。エレガントではありません

changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign 
changeDefense fDef [email protected](ShipDesign o d m rr s r sp st ...) = ShipDesign o (fDef d) m rr s r sp st ... 

。特にゲームでは、ステップごとにわずかな値を変更するのが一般的です。

私の質問は、よりエレガントな方法で単一の値を変更するライブラリ、デザインパターン、または他の方法がありますか?

答えて

15

はい、あなたはレコード更新の表記を使用することができます:あなたはそれと連携して

changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign 
changeDefense fDef sd = sd { defense = fDef (defense sd) } 

を、しかし、レコード更新の表記の限界は自分自身が表示されます、そして、あなたは何かがより強力になるでしょう。その時点で、lensesについて学習する必要があります。

+1

代わりに、レンズに直接ジャンプするのは、(少なくとも私の意見では)特殊な構文よりもはるかに機能的なソルーションを提供するからです。 – kqr

関連する問題