टेम्पलेट हास्केल के साथ संबद्ध प्रकार के समानार्थी शब्द प्राप्त करना


257

क्या टेम्पलेट हास्केल किसी प्रकार के वर्ग में घोषित संबंधित प्रकार के समानार्थक शब्द के नाम और / या घोषणा कर सकता है? मुझे उम्मीद थी reifyकि मैं जो चाहता हूं वह करूंगा, लेकिन यह सभी आवश्यक जानकारी प्रदान नहीं करता है। यह फ़ंक्शन प्रकार हस्ताक्षर प्राप्त करने के लिए काम करता है:

% ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
...
Prelude> -- I'll be inserting line breaks and whitespace for clarity
Prelude> -- in all GHCi output.
Prelude> :set -XTemplateHaskell 
Prelude> import Language.Haskell.TH
Prelude Language.Haskell.TH> class C a where f :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C)
ClassI (ClassD [] Ghci1.C [PlainTV a_1627398388] []
               [SigD Ghci1.f
                     (ForallT [PlainTV a_1627398388]
                              [ClassP Ghci1.C [VarT a_1627398388]]
                              (AppT (AppT ArrowT (VarT a_1627398388))
                                    (ConT GHC.Types.Int)))])
       []

हालाँकि, वर्ग में एक संबंधित प्रकार के पर्यायवाची को जोड़ने से आउटपुट में कोई परिवर्तन नहीं होता (नाम बदलने तक):

Prelude Language.Haskell.TH> :set -XTypeFamilies 
Prelude Language.Haskell.TH> class C' a where type F a :: * ; f' :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       []

अगर मुझे इसका नाम पता है F, तो मैं इसके बारे में जानकारी देख सकता हूं:

Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
                 Ghci3.F
                 [PlainTV a_1627405973]
                 (Just StarT))
        []

लेकिन मुझे Fपहली जगह में नाम नहीं मिला । यहां तक ​​कि अगर मैं टाइप क्लास का एक उदाहरण जोड़ता हूं, InstanceDतो परिभाषा के बारे में कोई भी जानकारी नहीं है:

Prelude Language.Haskell.TH> instance C' [a] where type F [a] = a ; f' = length
Prelude Language.Haskell.TH> f' "Haskell"
7
Prelude Language.Haskell.TH> 42 :: F [Integer]
42
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       [InstanceD []
                  (AppT (ConT Ghci3.C')
                        (AppT ListT (VarT a_1627406161)))
                  []]

यदि reifyकाम नहीं करेगा, तो क्या सहयोगी प्रकार के समानार्थक शब्द को मैन्युअल रूप से सूचीबद्ध करने के अलावा कोई वर्कअराउंड है?

यह समस्या जीएचसी 7.8.3 में टेम्पलेट-हैस्केल पैकेज के 2.9.0.0 संस्करण के साथ मौजूद है; यह टेम्पलेट-हैस्केल पैकेज के संस्करण 2.7.0.0 के साथ जीएचसी 7.4.2 में भी मौजूद था। (मैंने जीएचसी 7.6 पर जांच नहीं की। *, लेकिन मुझे लगता है कि यह वहां भी मौजूद था।) मुझे जीएचसी के किसी भी संस्करण के समाधान में दिलचस्पी है (इसमें "यह केवल जीएचसी संस्करण वी में तय किया गया था ")।


2
क्या आपने देखा reifyInstances?
Kwarrtz

2
@Kwarrtz: मैंने अभी इसकी कोशिश की। यह काम नहीं करता है, यद्यपि; यह सिर्फ उसी InstanceDs को जन्म देता है जैसा मैंने देखा था reify: इसका putStrLn $(stringE . show =<< reifyInstances ''C' =<< sequence [[t|[Int]|]])मूल्यांकन करता है [InstanceD [] (AppT (ConT Ghci1.C') (AppT ListT (VarT a_1627405978))) []], जिसमें परिवार के प्रकारों का अभाव है।
एंटाल स्पेक्टर-ज़बूसकी

1
मुझे यह अजीब लगता reifyहै कि आवश्यक जानकारी वापस नहीं आती है। शायद showकुछ जानकारी छिपा रहा है? क्या आपने Infoसीधे वस्तु की जांच करने की कोशिश की है ?
Kwarrtz

@Kwarrtz: मुझे डर लग रहा Infoहै Showउदाहरण सिर्फ एक प्राप्त होता है, और के लिए एक ही Showके लिए उदाहरण Dec। हालांकि, मैं भी सीधे जांच कर सकते हैं, जैसा कि आप से पूछा है, और कोई: putStrLn $(reify ''C' >>= \i -> case i of ClassI (ClassD _ _ _ _ [SigD _ _]) _ -> stringE "just a SigD" ; _ -> stringE "something else")पैदा करता है just a SigD- कि वास्तव में में केवल एक चीज है [Dec]में ClassD! (की आवश्यकता होती है LambdaCase)। मैं मानता हूँ कि यह अजीब है; इसीलिए मैंने यह सवाल पूछा :-)
एंटाल स्पेक्टर-ज़बूसकी

1
@ विश्वास: मुझे लगता है कि हम हिंसक समझौते में हैं - आपकी मूल टिप्पणी ने कहा कि यह एक शानदार विचार को आकर्षित करने के लिए पर्याप्त नहीं था, लेकिन इसने यूरास के जवाब को आकर्षित किया ! मैं बिल्कुल सहमत हूं कि एक अच्छा जवाब क्या है :-)
एंटाल स्पेक्टर-ज़बूसकी

जवाबों:


15

इसे लागू नहीं किया गया है क्योंकि किसी ने भी इसका अनुरोध नहीं किया है।

अजीब बात यह है कि TH अपने स्वयं के एएसटी का उपयोग करता है, जो आंतरिक संकलक के एएसटी का पालन नहीं करता है। परिणामस्वरूप, कोई भी नई सुविधा (जैसे संबद्ध प्रकार के परिवार) TH के माध्यम से स्वचालित रूप से उपलब्ध नहीं है। कुछ को एक टिकट खोलना होगा और इसे लागू करना होगा।

संदर्भ के लिए: आंतरिक reifyClassफ़ंक्शन संबंधित प्रकार के परिवारों की उपेक्षा करता है (यह टपल का 5 वाँ तत्व है classExtraBigSig, इसके द्वारा भी परिभाषा दी गई है ClassATItem।)

तकनीकी रूप से इसमें संबद्ध प्रकार के पारिवारिक समर्थन को लागू करना आसान होना चाहिए reify, लेकिन सबसे अधिक संभावना है कि इसे TH API में पिछड़े असंगत परिवर्तनों की आवश्यकता होगी, उदाहरण के लिए, क्योंकि इसका एएसटी संबद्ध प्रकार की चूक का समर्थन नहीं करता है।

जोड़ा गया: यह अब लागू किया गया है (एपीआई परिवर्तन btw के बिना) और शायद अगले ghcरिलीज में उपलब्ध होगा ।


1
@ एंटाल्स-जेड मेरा मतलब है कि संबद्ध प्रकार के पर्यायवाची चूक काFamilyD समर्थन नहीं करता है । आप शायद उनका उपयोग नहीं कर रहे हैं, लेकिन पूर्ण समाधान के लिए एपीआई परिवर्तन की आवश्यकता हो सकती है।
यूरास

5
@ अविश्वास, अंत तक इनाम को खुला छोड़ना भी अच्छे उत्तरों को आकर्षित करने में मदद करता है, इसलिए यह एक अच्छे उत्तर को पुरस्कृत करने की तुलना में जल्दी से पुरस्कृत करने का एक अधिक प्रभावी तरीका है।
दिफईर

1
बाउंटी अवधि समाप्त हो गई। यह सबसे अच्छा (और केवल) उत्तर है, जब तक या जब तक बग रिपोर्ट # 10891 हल नहीं हो जाती । शायद आपके उत्तर में बग रिपोर्ट के लिंक को शामिल करना एक अच्छा विचार है।
हाबिल

1
FYI करें, # 10891 निर्धारित है और यह विलय होने की प्रतीक्षा कर रहा है।
पापी

1
@SwiftsNamesake AFAIK ghc devs TH एपीआई को तोड़े बिना आंतरिक एएसटी को स्वतंत्र रूप से बदलना चाहते हैं। संभवतः अन्य कारण भी हैं।
यूरास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.