टी एल में एक रिकॉर्ड से खेतों को देख के लिए एक डीएसएल निर्माण करने के लिए कैसे; डॉ: मैं पता लगाना कैसे कोड है कि डेटा प्रकार (शायद सिर्फ डबल और बूल) की एक छोटी संख्या में से एक वापस आ जाएगी उत्पन्न करने के लिए मदद की जरूरत है अलग-अलग क्षेत्रों से अलग-अलग रिकॉर्डों पर।हास्केल
लांग प्रपत्र: निम्न डेटा प्रकारों
data Circle = Circle { radius :: Integer, origin :: Point }
data Square = Square { side :: Integer }
और कुछ बॉयलरप्लेट कोड
circle = Circle 3 (Point 0 0)
square = Square 5
मैं एक छोटे से डीएसएल निर्माण कर रहा हूँ, और यह मानते हुए उपयोगकर्ता की तरह कुछ लिखने होना चाहते हैं निम्नलिखित
circle.origin
square.side
और यह जी एनरेट कोड
origin . circle
side . square
इसे पार्स करने में, उदाहरण के लिए मेरे पास स्ट्रिंग "सर्कल" और "मूल" होगा। अब मुझे उन्हें फ़ंक्शन कॉल में बदलना होगा। मैं स्पष्ट रूप से इस तरह कुछ कर सकता था:
data Expr a = IntegerE (a -> Integer)
| PointE (a -> Point)
lookupF2I "side" = Just $ IntegerE side
lookupF2I "radius" = Just $ IntegerE radius
lookupF2I _ = Nothing
lookupF2P "origin" = Just $ PointE origin
lookupF2P _ = Nothing
और प्रति लौटा डेटा प्रकार में एक लुकअप फ़ंक्शन है। प्रति डेटा प्रकार के एक समारोह को डीएसएल के दृष्टिकोण से व्यावहारिक है कि यह केवल 2 या 3 डेटा प्रकारों से वास्तव में सौदा करेगा। हालांकि, यह मुश्किल से चीजों को करने का एक प्रभावी तरीका लगता है। क्या ऐसा करने का कोई बेहतर तरीका है (निश्चित रूप से)? यदि नहीं, तो क्या कोई तरीका है कि मैं विभिन्न रिकॉर्ड से विभिन्न लुकअप फ़ंक्शंस के लिए कोड जेनरेट कर सकता हूं जिन्हें मैं फ़ील्ड देखने में सक्षम होना चाहता हूं?
दूसरे, वहाँ अभी भी की बात है पार्स "circle"
या "square"
उचित circle
या square
फ़ंक्शन को कॉल करने की जरूरत है। हाथ लिखने के लिए होने
instance Lookup Circle where
lookupF2I "radius" = Just $ IntegerE radius
lookupF2I _ = Nothing
lookupF2P "origin" = Just $ PointE origin
lookupF2P _ = Nothing
लेकिन तब है कि मुझे यह पता लगाने की जो प्रकार देखने समारोह, पर लागू करने के लिए होने के साथ छोड़ देता है और बदतर: यदि मैं प्रकार वर्गों का उपयोग इस लागू करने के लिए थे, मैं की तरह कुछ कर सकता है प्रत्येक (कई) रिकॉर्ड के लिए उदाहरण जिन्हें मैं इसका उपयोग करना चाहता हूं।
नोट: तथ्य यह है कि Circle
और Square
का प्रतिनिधित्व किया जा सकता है एक एडीटी का उपयोग करके मेरे प्रश्न के लिए आकस्मिक है कि यह एक संक्षिप्त उदाहरण है। वास्तविक कोड में कई अलग-अलग रिकॉर्ड होंगे, जिनमें से एकमात्र चीज में समान रूप से समान प्रकार के फ़ील्ड होते हैं।
मैं लेंस पैकेज पर दिखेगा: http://hackage.haskell.org/package/lens-3.1 और भी विनाइल https://github.com/jonsterling/Vinyl – ErikR
+1 'lens' के लिए कम से। इसमें टेम्पलेट हास्केल समर्थन है ताकि आप स्वचालित रूप से डेटा प्रकारों से लेंस बना सकें। फिर आपका पार्सिंग कोड स्ट्रिंग्स को उनके संबंधित लेंस में अनुवाद करता है। –
ऐसा लगता है कि आप अपने डीएसएल को कुछ प्रकार के HOAS (उच्च ऑर्डर सार वाक्यविन्यास) के साथ एम्बेड कर रहे हैं जो एम्बेडेड भाषा में मेटा-भाषा (हास्केल) से फ़ंक्शंस का उपयोग करता है। यदि आप HOAS का उपयोग करने पर कुछ नोट्स चाहते हैं तो रॉबर्ट एटकी और सह-लेखकों https://personal.cis.strath.ac.uk/robert.atkey/unembedding.html द्वारा "अनमेडेडिंग" पेपर देखें। यदि होआस का मतलब आपके लिए कुछ भी नहीं है, तो आप शायद सामान्य पहले ऑर्डर सार वाक्यविन्यास के साथ सबसे अच्छे हैं - एक पहचानकर्ता के साथ बिल्टिन फ़ंक्शंस का प्रतिनिधित्व करते हैं और आदिम कार्यों के लिए एक लुकअप वाले वातावरण के साथ मूल्यांकन करते हैं। –