मैं नहीं जानता:
मैं निम्नलिखित स्निपेट द्वारा या Parsec द्वारा एक Read
उदाहरण लिख सकते हैं, लेकिन यह देखते हुए कि मैं TypeDec
और इस विभिन्न मॉड्यूल में Bar
लिए इसी तरह के कई प्रकार है एक बॉयलरप्लेट है एक सामान्य समाधान का। जैसा कि कहा गया है, यह readPrec
विधि को परिभाषित करते हुए Read
उदाहरणों लिखने के लिए एक बहुत आसान है (देखें Text.Read
विशेष रूप से, कुछ अतिरिक्त कार्यों के लिए Text.ParserCombinators.ReadPrec
, और शायद Text.ParserCombinators.ReadP
और भी अधिक के लिए) के बजाय Parsec
का उपयोग कर या readsPrec
को परिभाषित करने की। यह पूर्ण तेज़ नहीं है जिसे आप लिख सकते हैं, लेकिन यह उचित रूप से तेज़ होना चाहिए।
import Text.Read
instance Read Bar where
readListPrec = readListPrecDefault
readPrec = parens $ do
Ident "Bar" <- lexP
Ident td <- parens lexP
case td of
"TypeDecInt" -> Bar TypeDecInt <$> readPrec
"TypeDecString" -> Bar TypeDecString <$> readPrec
_ -> empty
तो TypeDec
अधिक जटिल है, और आप TypeDec Int
और TypeDec String
(FlexibleInstances
या एक सहायक वर्ग का प्रयोग करके) के लिए Read
मामले हैं तो फिर आप की संभावना कुछ अधिक मॉड्यूलर चाहता हूँ:
instance Read Bar where
readListPrec = readListPrecDefault
readPrec = parens $ do
Ident "Bar" <- lexP
(Bar <$> readPrec <*> (readPrec :: ReadPrec Int))
<|> (Bar <$> readPrec <*> (readPrec :: ReadPrec String))
ध्यान दें कि दूसरे उदाहरण में, जीएचसी अपने आप से यह नहीं समझ सकता कि विकल्पों के किस प्रकार के पास होना चाहिए, लेकिन जब हम दूसरे क्षेत्र के प्रकार को ठीक करते हैं, तो अनुमान पहले क्षेत्र में फैलता है। तो पहले विकल्प में, हम केवल "TypeDecInt"
देखेंगे और दूसरे में हम केवल "TypeDecString"
देखेंगे।
dependent-sum
पैकेज एक प्रकार है कि अपने Bar
सामान्यीकरण करता परिभाषित करता है।
data DSum tag f = forall a . !(tag a) :=> f a
यह भी कुछ अतिरिक्त कक्षाओं का उपयोग कर DSum
के लिए एक Read
उदाहरण परिभाषित करता है। सामान्य दृष्टिकोण ठोस दिखता है, लेकिन मैं दो परिवर्तनों की सिफारिश करता हूं। सबसे पहले सूचियों के साथ झगड़ा करने के बजाय ReadPrec
का उपयोग करना है। दूसरी निम्नलिखित (बहुत सरल) अस्तित्व एक साथ उच्च रैंक GReadResult
प्रकार बदलने के लिए है:
data GReadResult t = forall a . GReadResult (t a)
बेशक
, इन परिवर्तनों को यह अपने आप को लागू करने के लिए आप के लिए बाध्य करेगा, लेकिन यह ठीक है।
यह टेम्पलेट हास्केल का उपयोग कर पूरी तरह से करने योग्य है। किसी को सिर्फ @dfeuer द्वारा उल्लिखित दृष्टिकोण का उपयोग करने की आवश्यकता होगी (यानी 'GHC.Read.choose'' के बजाय 'केस' का उपयोग करना)। – Alec
@Alec क्या आप टेम्पलेट हास्केल के साथ 'रीड' उदाहरण प्राप्त करने के लिए कोई उदाहरण/ट्यूटोरियल जानते हैं? – homam
[यह] (https://wiki.haskell.org/Template_haskell/Instance_deriving_example) अच्छा लग रहा है। – Alec