2011-12-10 9 views
14

Decir que tengo el siguiente:¿Obtiene los nombres de campo de un registro Haskell como una lista de cadenas?

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

sample = Rec 1 2.3 4.5 

entiendo Plantilla Haskell & la función reify me puede conseguir nombres de los campos del registro. Es decir:

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

También se puede afirmar que esto se puede hacer sin Template Haskell. ¿Puede alguien proporcionar un ejemplo de implementación para esto?

+1

Puede obtener los nombres de los campos sin la plantilla Haskell también. – augustss

+1

@augustss: ¿Cómo? ¿Alguna magia negra "Typable"? De cualquier manera, la mayoría de los usos a los que se podría aplicar esta información encajarían perfectamente con Template Haskell. – delnan

+3

@delnan Puede usar 'Data.Data' o simplemente puede derivar' Show', show 'sample' y hacer un pequeño análisis sintáctico de esa cadena. – augustss

Respuesta

15

Se puede hacer con una instancia de Datos (la mayoría de las versiones de GHC) o Genéricas (7.2.x y superiores), que GHC puede derivar para usted. Aquí hay un ejemplo de cómo volcar campos de registro con la clase de datos Tipo:

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

También puede evitar tener que usar una instancia del tipo ('sample' en este caso) usando' print. constrFields del mapa. dataTypeConstrs. dataTypeOf $ (undefined :: Rec) '. Esto generará una lista de todos los campos en todos los constructores disponibles (y, por supuesto, se puede adaptar a su gusto) – dflemstr

Cuestiones relacionadas