Получить имена полей записи Haskell в виде списка строк?

Скажем, у меня есть следующее:

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

sample = Rec 1 2.3 4.5

Я понимаю, что Template Haskell и функция reify могут дать мне имена полей записи. Это:

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

Также есть утверждение, что это можно сделать без Template Haskell. Может ли кто-нибудь предоставить пример реализации для этого?


person Ana    schedule 10.12.2011    source источник
comment
Вы также можете получить имена полей без шаблона Haskell.   -  person augustss    schedule 10.12.2011
comment
@augustss: Как? Какая-то Typable черная магия? В любом случае, большинство вариантов использования этой информации отлично подходят для Template Haskell.   -  person    schedule 10.12.2011
comment
@delnan Вы можете либо использовать Data.Data, либо просто вывести Show, показать sample и выполнить небольшой анализ этой строки.   -  person augustss    schedule 11.12.2011
comment
Я не вижу много веских причин, чтобы на самом деле сделать это.   -  person Dan Burton    schedule 11.12.2011


Ответы (1)


Это можно сделать с помощью экземпляра Data (большинство версий GHC) или Generic (7.2.x и выше), который GHC может получить для вас. Вот пример того, как выводить поля записи с помощью класса типов данных:

{-# 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 
person Nathan Howell    schedule 10.12.2011
comment
Вы также можете избежать использования экземпляра типа (в данном случае sample), используя print . map constrFields . dataTypeConstrs . dataTypeOf $ (undefined :: Rec). Это создаст список всех полей во всех доступных конструкторах (и, конечно, может быть адаптирован по вашему вкусу) - person dflemstr; 10.12.2011