2011-12-10 5 views
14

Dire che ho il seguente:Ottieni i nomi dei campi di un record Haskell come un elenco di stringhe?

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

sample = Rec 1 2.3 4.5 

Capisco Template Haskell & la funzione reify mi può ottenere i nomi dei campi del record. Ovvero:

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

C'è anche una affermazione che questo può essere fatto senza Template Haskell. Qualcuno può fornire un'implementazione di esempio per questo può essere realizzato?

+1

È possibile ottenere i nomi dei campi senza modello Haskell. – augustss

+1

@augusts: come? Qualche magia nera 'tipizzabile'? In entrambi i casi, la maggior parte degli usi in cui si potrebbe mettere questa informazione sarebbe perfetta per Template Haskell. – delnan

+3

@delnan Puoi usare 'Data.Data' o puoi semplicemente derivare' Show', mostrare 'sample' e fare un piccolo parsing di quella stringa. – augustss

risposta

15

Può essere eseguito con una data (la maggior parte delle versioni di GHC) o un'istanza generica (7.2.xe successive), che GHC può derivare per voi. Ecco un esempio di come eseguire il dump dei campi di record con Data typeclass:

{-# 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

È anche possibile evitare di dover utilizzare un'istanza del tipo ('esempio' in questo caso) usando' stampa. mappa costrizioni. dataTypeConstrs. dataTypeOf $ (undefined :: Rec) '. Questo genererà un elenco di tutti i campi in tutti i costruttori disponibili (e può naturalmente essere adattato a tuo piacimento) – dflemstr