2011-12-15 14 views
36

द्वारा उत्पन्न कोड देखने के लिए पसंदीदा विधि जैसा कि आप जानते हैं, टेम्पलेट हास्केल का उपयोग संकलन-समय पर प्रोग्रामेटिक रूप से विभिन्न प्रकार के एएसटी स्प्लिसेस उत्पन्न करने के लिए किया जाता है।टेम्पलेट हास्केल

हालांकि, एक विभाजन अक्सर बहुत अपारदर्शी हो सकता है, और अक्सर यह पता लगाना मुश्किल होता है कि वास्तव में एक विभाजन क्या उत्पन्न करता है। यदि आप एक splice के लिए Q मोनैड चलाते हैं, और स्प्लिस अच्छी तरह से टाइप किया गया है, तो आपको show एएसटी के जेनरेट किए गए टुकड़े के सक्षम प्रतिनिधित्व मिलते हैं, लेकिन इसके प्रतिनिधित्व को इसके असंगठित लेआउट के कारण समझना बहुत मुश्किल हो सकता है।

TH-जेनरेटेड एएसटी के टुकड़े को सामान्य हास्केल कोड के समान रूपांतरित करने के लिए पसंदीदा तरीका क्या है, ताकि कोड आसानी से पढ़ और समझा जा सके? क्या कोई स्रोत कोड को पुनर्निर्माण कर सकता है उदा। एक Dec मूल्य दिया गया है? क्या किसी को जीएचसी कोर कोड पढ़ना है? क्या एएसटी को कम से कम संरचना करने का कोई तरीका है ताकि यह अधिक पठनीय हो जाए (उदाहरण के अलावा pretty-show पैकेज क्या करता है)?

उत्तर

22

आप Language.Haskell.TH.Ppr से pprint या ppr उपयोग करने में सक्षम हो सकता है:

GHCi> expr <- runQ [| \f g x -> f (x*2 + 3) . g |] 
GHCi> putStrLn $ pprint expr 
\f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1 

यह बहुत नहीं है, लेकिन यह वैध हास्केल है। आप प्रीलूड नामों से मॉड्यूल उपसर्ग को अलग करके आउटपुट नाइसर बनाने में सक्षम होना चाहिए (हालांकि आपको अपेक्षित उपसर्ग को केवल स्ट्रिप करने के लिए सावधान रहना पड़ सकता है; Foo.* पूरी तरह से वैध इंफिक्स ऑपरेटर है)।

+0

यह इस सवाल का हिस्सा हल करता है कि @augustss ने जवाब नहीं दिया था। – dflemstr

46

क्या आप -ddump-splices कंपाइलर को ध्वजांकित कर रहे हैं? (Language.Haskell.TH साथ स्वचालित रूप से आयात)

+2

हाँ, उत्पादन के इस प्रकार मैं के लिए ठीक क्या देख रहा हूँ है ! लेकिन क्या यह एक कार्यक्रम में भी किया जा सकता है, केवल एक वाक्यविन्यास पेड़ दिया जाता है, या क्या इसे संकलक के आविष्कार की आवश्यकता होती है? – dflemstr

+1

नोट: सुनिश्चित करें कि आप इसे चलाने से पहले क्लीन बिल्ड प्राप्त करने के लिए .hi और .o फ़ाइलों को हटा दें, या आपको कोई stderr आउटपुट नहीं मिलेगा। – RussellStewart

1

एक पूरक के रूप में ehird answer रहे हैं:

ध्यान दें कि runQ सीधे सामान्य रूप में उपयोग करते हुए GHCi से (उदा .: वें जनरेटर कि reify संचालन, cf. comments above the runQ declaration का उपयोग करें) काम न करे।

जब कि विफल रहता है, आप pprint (या show), परिचय एक स्ट्रिंग अभिव्यक्ति stringE तो एक तर्क के रूप ब्याह putStrLn को बदल सकता है:

> putStrLn $(stringE . pprint =<< [| \f g x -> f (x*2 + 3) . g |]) 
\f_0 g_1 x_2 -> f_0 ((x_2 GHC.Num.* 2) GHC.Num.+ 3) GHC.Base.. g_1