2015-10-07 3 views
5

je défini comme suit datatype enregistrementComment itérer sur des champs d'enregistrement?

data Config = Config 
    { field1 :: String 
    , field2 :: String 
    , field3 :: String 
    } 

Je veux itérer sur chaque champ de Config, appliquer une fonction String -> String, par exemple tail et obtenir en retour nouvelle Config.

Quelle est la manière idiomatique de faire cela? De préférence, sans bibliothèques tierces lourdes.

+2

La fonction '' head' renvoie une Char'. Ai-je raison de comprendre que vous voulez que le type de vos champs change en fonction de ce que la fonction fournie retourne? –

+1

uniplate est une bibliothèque générique légère qui peut probablement le faire facilement. – jberryman

+0

@MichaelSteele ma faute, quelque chose comme 'tail' qui retournera le même type' String'. J'ai mis à jour les questions –

Répondre

13

Eh bien, la meilleure façon de le faire serait probablement

{-# LANGUAGE DeriveFunctor #-} 

type Config = Config' String 
data Config' a = Config 
    { field1 :: a 
    , field2 :: a 
    , field3 :: a 
    } deriving (Functor) 

configHeads :: Config -> Config' Char 
configHeads = fmap head 
+0

monotraversable serait une alternative. –

+0

Pour les cordes, cela semble être la voie à suivre. Il est regrettable que cette approche empêche de bonnes optimisations dans d'autres situations. – dfeuer