मुसीबत
हास्केल में निम्नलिखित डिजाइन समस्या पर विचार करें। मेरे पास एक सरल, प्रतीकात्मक ईडीएसएल है जिसमें मैं चर और सामान्य अभिव्यक्ति (बहुभिन्नरूपी बहुपद) जैसे कि व्यक्त करना चाहता हूं x^2 * y + 2*z + 1
। इसके अलावा, मैं अभिव्यक्तियों पर कुछ प्रतीकात्मक समीकरणों को कहना चाहता हूं x^2 + 1 = 1
, साथ ही परिभाषाओं को भी पसंद करता हूं x := 2*y - 2
।
लक्ष्य यह है:
- चर और सामान्य अभिव्यक्ति के लिए एक अलग प्रकार है - कुछ कार्यों को चर पर लागू किया जा सकता है और जटिल अभिव्यक्ति नहीं। उदाहरण के लिए, एक परिभाषा ऑपरेटर
:=
प्रकार का हो सकता है(:=) :: Variable -> Expression -> Definition
और इसके बाईं ओर के पैरामीटर के रूप में एक जटिल अभिव्यक्ति को पारित करना संभव नहीं होना चाहिए (हालांकि स्पष्ट कास्टिंग के बिना इसके दाहिने हाथ के पैरामीटर के रूप में एक चर को पारित करना संभव होना चाहिए ) । - अभिव्यक्ति का एक उदाहरण है
Num
, ताकि पूर्णांक शाब्दिक अभिव्यक्ति को बढ़ावा देने और कुछ सहायक आवरण ऑपरेटरों को शुरू किए बिना जोड़ या गुणा जैसे सामान्य बीजीय संचालन के लिए एक सुविधाजनक अंकन का उपयोग करना संभव हो।
दूसरे शब्दों में, मैं अभिव्यक्ति के लिए एक अंतर्निहित और स्थिर प्रकार कास्ट (जबरदस्ती) रखना चाहूंगा । अब, मुझे पता है कि जैसे कि, हास्केल में कोई निहित प्रकार की जातियां नहीं हैं। फिर भी, कुछ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग अवधारणाओं (सरल विरासत, इस मामले में) कर रहे हैं व्यक्त , हास्केल के प्रकार प्रणाली में या तो साथ या भाषा एक्सटेंशन के बिना। एक हल्के वाक्यविन्यास को रखते हुए मैं उपरोक्त दोनों बिंदुओं को कैसे संतुष्ट कर सकता हूं? क्या यह भी संभव है?
विचार-विमर्श
यह स्पष्ट है कि यहाँ मुख्य समस्या है Num
प्रतिबंध, जैसे
(+) :: Num a => a -> a -> a
सिद्धांत रूप में, एक एकल (सामान्यीकृत) बीजीय डेटा प्रकार को चर और भाव दोनों के लिए लिखना संभव है। फिर, कोई :=
इस तरह से लिख सकता है , कि बाएं हाथ की अभिव्यक्ति में भेदभाव किया जाता है और केवल एक रनवे निर्माता को स्वीकार किया जाता है, एक रन-टाइम त्रुटि के साथ अन्यथा। हालांकि यह एक साफ, स्थिर (संकलन-समय) समाधान नहीं है ...
उदाहरण
आदर्श रूप से, मैं एक हल्के वाक्यविन्यास को प्राप्त करना चाहूंगा जैसे कि
computation = do
x <- variable
t <- variable
t |:=| x^2 - 1
solve (t |==| 0)
विशेष रूप से, मैं इस तरह t + 1 |:=| x^2 - 1
से संकेतन की :=
परिभाषा देना चाहता हूं
क्योंकि एक चर की परिभाषा देनी चाहिए न कि पूरे बाएं हाथ की अभिव्यक्ति।
FromVar
टाइपकास्ट कैसे मदद का होगा। मैं Expr
एक उदाहरण रखते हुए स्पष्ट जातियों से बचना चाहता हूं Num
। मैंने एक संकेतन का उदाहरण जोड़ते हुए प्रश्न को संपादित किया जिसे मैं प्राप्त करना चाहूंगा।
class FromVar e
एक विधि के साथfromVar :: Variable -> e
और के लिए उदाहरणों प्रदानExpression
औरVariable
, फिर अपने चर बहुरूपी प्रकार है हैx :: FromVar e => e
आदि मैं परीक्षण नहीं किया है कितनी अच्छी तरह यह काम करता है के बाद से मैं अपने फोन पर कर रहा हूँ।