निम्न प्रकार के हस्ताक्षर पर विचार करें:स्वतंत्र विकल्प functor से optparse-अनुप्रयोगी पार्सर उत्पन्न
data Foo x = Foo {
name :: String
, reader :: String -> x
}
instance Functor Foo where
fmap f (Foo n r) = Foo n $ f . r
अब मैं से एक प्राकृतिक परिवर्तन दिखाने Foo
optparse-applicative
करने के Parser
प्रकार:
import qualified Options.Applicative as CL
mkParser :: Foo a -> CL.Parser a
mkParser (Foo n _) = CL.option CL.disabled (CL.long n)
(ठीक है, यह थोड़ा बेकार है, लेकिन यह चर्चा के लिए काम करेगा)।
अब मैं Bar
ले Foo
से अधिक स्वतंत्र विकल्प functor होने के लिए:
type Bar a = Alt Foo a
को देखते हुए यह एक नि: शुल्क functor है, मैं Parser
को Bar
से एक प्राकृतिक परिवर्तन में mkParser
लिफ्ट करने के लिए सक्षम होना चाहिए:
foo :: String -> (String -> x) -> Bar x
foo n r = liftAlt $ Foo n r
myFoo :: Bar [String]
myFoo = many $ foo "Hello" (\_ -> "Hello")
clFoo :: CL.Parser [String]
clFoo = runAlt mkParser $ myFoo
और वास्तव में, यह काम करता है और मुझे Parser
वापस देता है। हालांकि, यह एक बहुत बेकार है, क्योंकि इसके साथ बहुत कुछ करने की कोशिश करने से अनंत लूप होता है। उदाहरण के लिए, यदि मैं इसका वर्णन करने का प्रयास करता हूं:
CL.cmdDesc clFoo
> Chunk {unChunk =
और बाधित होने तक लटकता है। यह कवर के तहत monadic पार्स उपयोग करता है:
इस का कारण यह है कि optparse-applicative
cheatsmany
और some
की अपनी परिभाषा में हो रहा है।
क्या मैं यहां कुछ गलत कर रहा हूं? मैं नहीं देखता कि, यह कैसे दिया गया है, इस तरह से एक पार्सर बनाना संभव है। कोई विचार?
आप 'many' और' some' कंस्ट्रक्टर्स को भी शामिल करने के लिए स्वतंत्र अनुप्रयोगी का विस्तार कर सकता है और फिर उन्हें एक छोटे से व्याख्या अलग ढंग से, शायद। –