2011-12-14 18 views
6

ho qualche boilerplate Haskell che sembra qualcosa di simile:Haskell dinamica dei dati di tipo alterazione

data Configuration 
    { confA :: Integer 
    , confB :: Boolean 
    , confC :: String } 

x = (\arg opt -> opt{ confA=arg }) 
y = (\arg opt -> opt{ confB=arg }) 
z = (\arg opt -> opt{ confC=arg }) 

e mi piacerebbe per rimuovere il testo standard, cedendo qualcosa sulla falsariga di:

setter :: (Config -> a) -> a -> Config -> Config 
x = setter confA 
y = setter confB 
z = setter confC 

Ma non ho idea di come costruire una tale funzione setter. Questo è possibile anche in haskell (non template) o sto facendo un confronto con lo zucchero della sintassi qui? Se sì, come farei una cosa del genere in haskell modello?

risposta

13

Questo non è possibile con il solo sistema di registrazione Haskell. Quello che vuoi sono gli obiettivi ; questo previous Stack Overflow question e la sua risposta migliore sono una buona introduzione. Personalmente, io uso il pacchetto data-lens parlato lì. (Vedi anche data-lens-fd di usarlo con la classe MonadState da mtl - se non si sa di cosa si tratta, è sufficiente sapere che probabilmente si dovrebbe usare ogni volta che si desidera utilizzare le lenti in un State monade.)

Il data-lens-template il pacchetto potrebbe essere l'applicazione di Template Haskell che si desidera; deriva le definizioni dell'obiettivo per i campi record.

L'altro pacchetto di lenti popolare è fclabels. Preferisco la lente dei dati per la sua semplicità e velocità; fclabels (a partire dalla versione 1.0) è leggermente più flessibile, ma non hai bisogno di quella flessibilità per quello che vuoi fare. (Si noti che a causa della flessibilità appena aumentata, il tipo (:->) di fclabels non può più essere tradotto direttamente nella semplice definizione di obiettivi, come indicato nella risposta Overflow dello stack I collegata.)

1

Questo non è possibile senza Template Haskell. È possibile utilizzare l'accesso ai dati e il modello di accesso ai dati per rimuovere tale piastra di caldaia.

+0

Credo sia corretto. Registra la sintassi crea automaticamente * getters * per te, ma quelli sono per lo più inutili quando si desidera creare * setter *. –