2013-07-08 6 views
11

Per esempio, io hoCome "cambiare" singoli valori in oggetti di grandi dimensioni in modo elegante?

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

Ora voglio cambiare la difesa. Il modo conosciuto per farlo è:

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 ... 

che non è elegante. Soprattutto nei giochi è comune cambiare solo alcuni valori per passo.

La mia domanda è: c'è una biblioteca, un modello di progettazione o un altro modo per modificare un singolo valore in modo più elegante?

risposta

15

Sì, è possibile utilizzare record di aggiornamento notazione:

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

Come si lavora con esso, però, i limiti di aggiornamento notazione Will mostrare se stessi, e si vuole qualcosa di più potente. A quel punto, dovresti iniziare a conoscere lenses.

+1

Un'alternativa è di saltare direttamente negli obiettivi, poiché essi (almeno secondo me) forniscono una soluzione molto più funzionale al problema rispetto a una sintassi speciale. – kqr

Problemi correlati