मैं वैक्टर और मैट्रिस के साथ खेल रहा हूं जहां आकार DataKinds
एक्सटेंशन का उपयोग करके उनके प्रकार में एन्कोड किया गया है। यह मूल रूप से इस प्रकार है:पुनरावर्ती रूप से परिभाषित उदाहरण और बाधा
data Nat = Zero | Succ Nat
data Vector :: Nat -> * -> * where
VNil :: Vector Zero a
VCons :: a -> Vector n a -> Vector (Succ n) a
अब हम Functor
और Applicative
जैसे विशिष्ट उदाहरणों चाहते हैं। Functor
आसान है:
instance Functor (Vector n) where
fmap f VNil = VNil
fmap f (VCons a v) = VCons (f a) (fmap f v)
लेकिन Applicative
उदाहरण के साथ कोई समस्या है: हम किस प्रकार शुद्ध में वापस जाने के लिए पता नहीं है। हालांकि, हम वेक्टर के आकार पर उपपादन उदाहरण परिभाषित कर सकते हैं:
instance Applicative (Vector Zero) where
pure = const VNil
VNil <*> VNil = VNil
instance Applicative (Vector n) => Applicative (Vector (Succ n)) where
pure a = VCons a (pure a)
VCons f fv <*> VCons a v = VCons (f a) (fv <*> v)
हालांकि, भले ही इस उदाहरण पर लागू होता है सभी वैक्टर के लिए, टाइप करें चेकर इस पता नहीं है, तो हम Applicative
बाधा ले जाने के लिए है हर बार जब हम उदाहरण का उपयोग करते हैं।
अब, अगर यह केवल Applicative
उदाहरण पर लागू होता है तो यह कोई समस्या नहीं होगी, लेकिन यह पता चला है कि इस तरह के प्रकार के साथ प्रोग्रामिंग करते समय रिकर्सिव इंस्टेंस घोषणाओं की चाल आवश्यक है। उदाहरण के लिए, अगर हम TypeCompose लाइब्रेरी का उपयोग पंक्ति वैक्टर का एक वेक्टर के रूप में एक मैट्रिक्स,
type Matrix nx ny a = (Vector nx :. Vector ny) a
परिभाषित हम एक प्रकार वर्ग को परिभाषित करने और दोनों पक्षांतरित और आव्यूह गुणन लागू करने के लिए पुनरावर्ती उदाहरण घोषणाओं को जोड़ने के लिए है। यह हर बार जब हम कोड का उपयोग करते हैं, तब हमें बाधाओं का एक विशाल प्रसार होता है, भले ही उदाहरण वास्तव में सभी वैक्टरों और मैट्रिस पर लागू होते हैं (बाधाओं को बेकार बनाते हैं)।
क्या इन सभी बाधाओं को दूर करने से बचने का कोई तरीका है? क्या टाइप चेकर का विस्तार करना संभव होगा ताकि यह ऐसे अपरिवर्तनीय निर्माण का पता लगा सके?
कुछ पढ़ने और कुछ प्रयोग के बाद, मैंने अंततः इस जवाब को समझ लिया है। असल में हैस्नाट्टी बाधा आपको अतिरिक्त स्तर की आवश्यकता को दूर करने, प्रकार के स्तर के बजाय मूल्य स्तर पर रिकर्सन करने की अनुमति देती है। इससे बहुत मदद मिलती है। हालांकि, मैं वास्तव में ट्रैवर्सबल के संदर्भ में मैट्रिक्स गुणा को कार्यान्वित करने के तरीके को देखने के लिए संघर्ष कर रहा हूं। क्या आप कुछ संकेत प्रदान कर सकते हैं? मैट्रिक्स गुणा के अधिकांश कार्यान्वयन पहले matrices में से एक transposes। क्या आप ट्रैवर्सबल के साथ मैट्रिक्स ट्रांसफर कर सकते हैं? – Almanildo
हां।यदि आपके पास 'आवेदक' और 'ट्रैवर्सबल' के लिए उपर्युक्त उदाहरण हैं, तो 'ट्रांसफर' 'ट्रैवर्स आईडी 'है। इसे देखने के लिए, पहले प्रकारों की जांच करें। 'ट्रैवर्स :: आवेदक वीएम => (एस -> वीएम टी) -> वेक्टर एनएस -> वीएम (वेक्टर एनटी) 'और अब' वीएम = वेक्टर एम' और' एस = वेक्टर एमटी 'लेते हुए, हमें' ट्रैवर्स आईडी 'मिलता है: : वेक्टर एन (वेक्टर एमटी) -> वेक्टर एम (वेक्टर एनटी) '। ऑपरेशनल रूप से, 'ट्रैवर्स आईडी' 'VNil' को 'VNil' के वेक्टर में ले जाता है, और शीर्ष पंक्ति में वेक्टरिज्ड-'VCons' और शेष का स्थानांतरण करता है, जिससे शीर्ष पंक्ति बाईं ओर कॉलम में होती है। – pigworker
ठीक है, लेकिन अभी भी आंतरिक वेक्टर पर हैसनाटी बाधा की जरूरत है। हालांकि, अच्छा है, धन्यवाद। – Almanildo