उदाहरण के लिए, regular लाइब्रेरी का उपयोग करके किया जा सकता है।
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
import Control.Applicative
import Generics.Regular
कम से कम सबसे लोकप्रिय पार्सर Combinator लाइब्रेरी के दो एक अनुप्रयोगी-functor इंटरफेस के साथ आते हैं:: इस लाइब्रेरी के साथ कार्य करना आम तौर पर कुछ भाषा एक्सटेंशन की आवश्यकता है उदाहरण के लिए देखते हैं,, uu-parsinglib और parsec, लेकिन चीजों को सरल बनाने के लिए आइए यहां सरल सूची-सफल सफलता पार्सर्स का उपयोग करें।
newtype Parser a = Parser {runParser :: ReadS a}
instance Functor Parser where
fmap f p = Parser $ \s -> [(f x, s') | (x, s') <- runParser p s]
instance Applicative Parser where
pure x = Parser $ \s -> [(x, s)]
p <*> q = Parser $ \s ->
[(f x, s'') | (f, s') <- runParser p s, (x, s'') <- runParser q s']
instance Alternative Parser where
empty = Parser $ \_ -> []
p <|> q = Parser $ \s -> runParser p s ++ runParser q s
(। कि नोट type ReadS a = String -> [(a, String)]
)
pSym :: Char -> Parser Char
pSym c = Parser $ \s -> case s of
(c' : s') | c == c' -> [(c', s')]
_ -> []
pInt :: Parser Int
pInt = Parser reads
pFloat :: Parser Float
pFloat = Parser reads
सीधी, हमने:
class Parseable a where
getParser :: Parser a
instance Parseable Int where
getParser = pInt
instance Parseable Float where
getParser = pFloat
और, अपने रिकॉर्ड प्रकार के लिए, के रूप में वांछित:
data Record = Record {i :: Int, f :: Float}
instance Parseable Record where
getParser = Record <$> pInt <* pSym ' ' <*> pFloat
अब , हम सामान्य रूप से कैसे करते हैं ऐसे पार्सर उत्पन्न करें? तब
type instance PF Record = K Int :*: K Float
, हम Record
प्रकार वर्ग Regular
का एक उदाहरण बनाने:
सबसे पहले, हम Record
के तथाकथित पैटर्न functor (विवरण के लिए regular के दस्तावेज़ देखें) को परिभाषित
instance Regular Record where
from (Record n r) = K n :*: K r
to (K n :*: K r) = Record n r
class ParseableF f where
getParserF :: Parser a -> Parser (f a)
instance ParseableF (K Int) where
getParserF _ = K <$> pInt
instance ParseableF (K Float) where
getParserF _ = K <$> pFloat
instance (ParseableF f, ParseableF g) => ParseableF (f :*: g) where
getParserF p = (:*:) <$> getParserF p <* pSym ' ' <*> getParserF p
:
इसके बाद, हम एक सामान्य पार्सर को परिभाषित
अब (सभी नियमित प्रकारों को कवर करने के लिए, आप कुछ और उदाहरणों प्रदान करना होगा, लेकिन इन आपके उदाहरण के लिए कर सकते हैं।)
, हम प्रदर्शन कर सकते हैं कि वर्ग Regular
में हर प्रकार के (दिए गए के लिए एक ParseableF
उदाहरण इसका पैटर्न फ़ैक्टर) एक पार्सर के साथ आता है:
instance (Regular a, ParseableF (PF a)) => Parseable a where
getParser = to <$> getParserF getParser
चलिए इसे स्पिन के लिए लेते हैं। Parseable
(यानी Int
, Float
, और निश्चित रूप से Record
) के मूल उदाहरण ड्रॉप करें और केवल एक सामान्य उदाहरण रखें।ये हम चले:
> runParser (getParser :: Parser Record) "42 3.14"
[(Record {i = 42, f = 3.14},"")]
नोट: यह कैसे नियमित रूप से पुस्तकालय का उपयोग कर सामान्य पारसर्स प्राप्त करने के लिए का सिर्फ एक बहुत ही बुनियादी उदाहरण है। लाइब्रेरी स्वयं generic list-of-successes parser के साथ आता है जो रिकॉर्ड के साथ विशेष रूप से अच्छी चीजें करता है। आप इसे पहले बाहर देखना चाह सकते हैं। इसके अलावा, लाइब्रेरी टेम्पलेट हास्केल समर्थन के साथ आता है ताकि Regular
के उदाहरण स्वचालित रूप से प्राप्त किए जा सकें। इन उदाहरणों में रिकॉर्ड लेबल के लिए विशेष संरचना प्रकार शामिल हैं, ताकि आप अपने सामान्य कार्य रिकॉर्ड प्रकारों को वास्तव में फैंसी का इलाज कर सकें। दस्तावेज़ देखें।
बस स्पष्ट करने के लिए: यदि आप 'Parseable Record' के लिए एक उदाहरण चाहते हैं आप के लिए उत्पन्न करने की? – kosmikus