2011-12-10 1 views
14

Dire que je donne les résultats suivants:Obtenir les noms de champs d'un enregistrement Haskell sous la forme d'une liste de chaînes?

data Rec = Rec { 
    alpha :: Int, 
    beta :: Double, 
    phi :: Float 
} 

sample = Rec 1 2.3 4.5 

Je comprends modèle Haskell & la fonction reify peut me faire les noms des champs de l'enregistrement. C'est-à-dire:

print $(f sample) --> ["alpha", "beta", "phi"] 

Il est également indiqué que ceci peut être fait sans modèle Haskell. Quelqu'un peut-il fournir un exemple de mise en œuvre pour cela peut être accompli?

+1

Vous pouvez également obtenir les noms de champs sans le modèle Haskell. – augustss

+1

@augustss: Comment? De la magie noire 'Typable'? De toute façon, la plupart des utilisations que l'on pourrait mettre cette information serait un bon ajustement pour Template Haskell. – delnan

+3

@delnan Vous pouvez utiliser 'Data.Data' ou vous pouvez simplement dériver' Show', montrer 'sample' et faire un peu d'analyse de cette chaîne. – augustss

Répondre

15

Cela peut être fait avec une instance Data (la plupart des versions GHC) ou Generic (7.2.x et plus), que GHC peut dériver pour vous. Voici un exemple de comment vider des champs d'enregistrement avec la classe de données Data:

{-# LANGUAGE DeriveDataTypeable #-} 

import Data.Data 

data Rec = Rec { 
    alpha :: Int, 
    beta :: Double, 
    phi :: Float 
} deriving (Data, Typeable) 

sample = Rec 1 2.3 4.5 

main :: IO() 
main = print . constrFields . toConstr $ sample 
+5

Vous pouvez également éviter d'utiliser une instance du type ('sample' dans ce cas) en utilisant' print. map constrFields. dataTypeConstrs. dataTypeOf $ (undefined :: Rec) '. Cela générera une liste de tous les champs dans tous les constructeurs disponibles (et peut bien sûr être adapté à votre goût) – dflemstr

Questions connexes