Get a Haskell record's field names as a list of strings?
Asked Answered
E

1

18

Say I have the following:

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

sample = Rec 1 2.3 4.5

I understand Template Haskell & the reify function can get me the record's field names. That is:

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

There is also a claim that this can be done without Template Haskell. Can someone provide an example implementation for this can be accomplished?

Expecting answered 10/12, 2011 at 16:10 Comment(4)
You can get the field names without template Haskell too.Kenton
@augustss: How? Some Typable black magic? Either way, most uses one could put this information to would be a great fit for Template Haskell.Georgy
@delnan You can either use Data.Data or you can just derive Show, show sample and do a little parsing of that string.Kenton
I don't see many compelling reasons to actually do this.Leena
P
19

It can be done with a Data (most GHC versions) or Generic (7.2.x and up) instance, which GHC can derive for you. Here's an example of how to dump record fields with the 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 
Planter answered 10/12, 2011 at 16:48 Comment(1)
You can also avoid having to use an instance of the type (sample in this case) by using print . map constrFields . dataTypeConstrs . dataTypeOf $ (undefined :: Rec). This will generate a list of all the fields in all of the available constructors (and can of course be tailored to your liking)Travelled

© 2022 - 2024 — McMap. All rights reserved.