2012-07-20 16 views
10

मान लीजिए मैं एक मनमाना मॉड्यूलएक रिकार्ड

module Foo where 
foo :: Moo -> Goo 
bar :: Car -> Far 
baz :: Can -> Haz 

जहां foo, bar, और baz सही ढंग से लागू कर रहे हैं में एक मॉड्यूल वस्तु के बारे में जैसे सोचना, आदि

मैं एक स्वत: में इस मॉड्यूल वस्तु के बारे में जैसे सोचना करना चाहते हैं - जनरेटेड डेटा प्रकार और संबंधित ऑब्जेक्ट:

import Foo (Moo, Goo, Car, Far, Can, Haz) 
import qualified Foo 

data FooModule = Foo 
    { foo :: Moo -> Goo 
    , bar :: Car -> Far 
    , baz :: Can -> Haz 
    } 

_Foo_ = Foo 
    { foo = Foo.foo 
    , bar = Foo.bar 
    , baz = Foo.baz 
    } 

नाम मूल मॉड्यूल के समान ही होना चाहिए।

मैं इसे हाथ से कर सकता था, लेकिन यह बहुत कठिन है, इसलिए मैं इस काम को करने के लिए कुछ कोड लिखना चाहता हूं।

मुझे सच में यकीन नहीं है कि इस तरह के कार्य को कैसे पहुंचाया जाए। क्या टेम्पलेट हास्केल मॉड्यूल का निरीक्षण करने का एक तरीका प्रदान करता है? क्या मुझे कुछ जीएचसी एपीआई में लगा देना चाहिए? या क्या मैं हडॉक पृष्ठों को स्क्रैप करने जैसे अधिक विज्ञापन-प्रसार दृष्टिकोण के साथ भी बंद हूं?

+3

क्या आप मॉड्यूल स्रोत को पार्स करने के लिए 'हैकेल-src-exts' का उपयोग कर सकते हैं, फिर उस से अपना डेटाटाइप बनाएं और एक नई स्रोत फ़ाइल आउटपुट करें? –

+0

हैकेल-src-exts एक अच्छा विचार है, लेकिन स्रोत को पार्स करना पर्याप्त रूप से पर्याप्त नहीं होगा। उदाहरण के लिए, [Data.Map] के लिए स्रोत (http://hackage.haskell.org/packages/archive/containers/0.5.0.0/doc/html/src/Data-Map.html) बस डेटा को फिर से निर्यात करता है। नक्शा। कुछ अतिरिक्त चीजों के साथ आलसी। मुझे सभी निर्यातों के पारगमन बंद होने की आवश्यकता है जो एक दिए गए मॉड्यूल वास्तव में निर्यात करता है। स्रोत का निरीक्षण किए बिना मॉड्यूल डेटा निकालने में भी सक्षम होना अच्छा होगा। –

उत्तर

3

(यह जीएचसी-7.4.2 के लिए है; यह शायद Outputable में कुछ बदलावों के कारण HEAD या 7.6 से संकलित नहीं होगा)। मुझे TH में मॉड्यूल का निरीक्षण करने के लिए कुछ भी नहीं मिला।

{-# LANGUAGE NoMonomorphismRestriction #-} 
{-# OPTIONS -Wall #-} 
import GHC 
import GHC.Paths -- ghc-paths package 
import Outputable 
import GhcMonad 

main :: IO() 
main = runGhc (Just libdir) $ goModule "Data.Map" 

goModule :: GhcMonad m => String -> m() 
goModule modStr = do 
    df <- getSessionDynFlags 
    _ <- setSessionDynFlags df 
    --^Don't know if this is the correct way, but it works for this purpose 

    setContext [IIDecl (simpleImportDecl (mkModuleName modStr))] 
    infos <- mapM getInfo =<< getNamesInScope 
    let ids = onlyIDs infos 
    liftIO . putStrLn . showSDoc . render $ ids 

onlyIDs :: [Maybe (TyThing, Fixity, [Instance])] -> [Id] 
onlyIDs infos = [ i | Just (AnId i, _, _) <- infos ] 

render :: [Id] -> SDoc 
render ids = mkFields ids $$ text "------------" $$ mkInits ids 

mkFields :: [Id] -> SDoc 
mkFields = vcat . map (\i -> 
    text "," <+> pprUnqual i <+> text "::" <+> ppr (idType i)) 

mkInits :: [Id] -> SDoc 
mkInits = vcat . map (\i -> 
    text "," <+> pprUnqual i <+> text "=" <+> ppr i) 


-- * Helpers 

withUnqual :: SDoc -> SDoc 
withUnqual = withPprStyle (mkUserStyle neverQualify AllTheWay) 

pprUnqual :: Outputable a => a -> SDoc 
pprUnqual = withUnqual . ppr 
संबंधित मुद्दे