2012-03-03 16 views
17

मेरा मतलब है कि एक प्रकार के वर्ग के उदाहरण को परिभाषित करना है जो एक स्थानीय (let या where) फ़ंक्शन में दायरे में लागू होता है। सबसे महत्वपूर्ण बात यह है कि, मैं इस उदाहरण में फ़ंक्शंस बंद करना चाहता हूं, यानी लेक्सिकल स्कोप में वेरिएबल्स को बंद करने में सक्षम होना चाहिए जहां इंस्टेंस परिभाषित किया गया है (जिसका अर्थ यह है कि अगली बार जब फ़ंक्शन में होता है तो उदाहरण अलग-अलग काम कर सकता है)।क्या "स्थानीय" टाइपक्लास उदाहरण होना संभव है?

मैं आपको इसके लिए एक सरल उपयोग केस दे सकता हूं। मान लीजिए मेरे पास एक ऐसा फ़ंक्शन है जो किसी प्रकार के वर्ग के आधार पर संचालित होता है। इस उदाहरण में मैं स्क्वायरिंग का उपयोग करता हूं, जो Num (हां, स्क्वायरिंग बहुत सरल है और इसे आसानी से फिर से कार्यान्वित किया जा सकता है, लेकिन यह कुछ जटिल हो सकता है) के लिए खड़ा है। मुझे मौजूदा फ़ंक्शन का उपयोग करने में सक्षम होना चाहिए (इसे बदलने या इसे फिर से कार्यान्वित किए बिना)।

square :: Num a => a -> a 
square x = x * x 

अब, मैं मॉड्यूलर अंकगणितीय, यानि कि इसके अलावा, गुणा, आदि आधुनिक कुछ संख्या में इस आपरेशन का उपयोग करना चाहते लगता है। किसी भी निश्चित मॉड्यूलो बेस के लिए इसे कार्यान्वित करना आसान होगा, लेकिन मैं कुछ सामान्य बनाना चाहता हूं कि मैं विभिन्न मॉड्यूलो बेस के लिए पुनः उपयोग कर सकता हूं। मैं कुछ इस तरह परिभाषित करने के लिए सक्षम होना चाहते हैं:

newtype ModN = ModN Integer deriving (Eq, Show) 

-- computes (x * x) mod n 
squareModN :: 
squareModN x n = 
    let instance Num ModN where 
    ModN x * ModN y = ModN ((x * y) `mod` n) -- modular multiplication 
    _ + _ = undefined   -- the rest are unimplemented for simplicity 
    negate _ = undefined 
    abs _ = undefined 
    signum _ = undefined 
    fromInteger _ = undefined 
    in let ModN y = square (ModN x) 
    in y 

इस की बात है कि मैं ऊपर से समारोह उपयोग करने की आवश्यकता है (square) है कि इसके तर्क एक प्रकार एक निश्चित का एक उदाहरण है कि होने की आवश्यकता है वर्ग टाइप करें। मैं एक नया प्रकार परिभाषित करता हूं और इसे Num का उदाहरण देता हूं; हालांकि, इसके लिए मॉड्यूलो अंकगणितीय सही तरीके से करने के लिए, यह मॉड्यूलो बेस n पर निर्भर करता है, जो इस फ़ंक्शन के सामान्य डिज़ाइन के कारण कॉल से कॉल में बदल सकता है। मैं square फ़ंक्शन के लिए इस समय (और केवल इस बार) ऑपरेशन को कस्टमाइज़ करने के तरीके के लिए उदाहरण कार्यों को एक बार "कॉलबैक" (यदि आप करेंगे) के रूप में परिभाषित करना चाहते हैं।

एक समाधान "क्लोजर वेरिएबल्स" को सीधे डेटाटाइप में एकीकृत करने के लिए हो सकता है (यानी ModN (x, n) उस संख्या और आधार का प्रतिनिधित्व करने के लिए), और संचालन केवल इस जानकारी को तर्क से निकाल सकते हैं। हालांकि, इसमें कई समस्याएं हैं: 1) बहु-तर्क कार्यों के लिए (उदा। (*)) इसे रनटाइम पर जांचना होगा कि ये जानकारी मेल खाती है, जो बदसूरत है; और 2) उदाहरण में 0-तर्क "मान" हो सकते हैं जो मैं बंद चर पर निर्भर होना चाहूंगा, लेकिन, क्योंकि उनमें कोई तर्क नहीं है, उन्हें तर्क से निकाला नहीं जा सकता है।

+2

नहीं, आपके पास स्थानीय उदाहरण नहीं हो सकते हैं। मॉड्यूलर अंकगणित ओलेग Kiselyov और सीसी शान के लिए उनके कागज "लागू विन्यास" में समस्या हल हो गई है - http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf। व्यक्तिगत रूप से मैं इससे बचने के लिए और मॉड्यूलर आधार के लिए एक नया प्रकार बना देता हूं - यानी जेड 7, जेड 12। कोनल इलियट के पास वैकल्पिक प्रकार के वर्गों का चयन करने के लिए एक और पैटर्न है, पेपर "सीएसएममोनाइड" पेपर "आवेदक डेटा-संचालित गणना" में देखें - http://conal.net/papers/data-driven/paper.pdf –

+1

दरअसल, प्रतिबिंब पैकेज अनिवार्य रूप से है ओलेग पेपर का पैक संस्करण। – ehird

+0

हास्केल की वर्तमान स्थिति के बारे में: नहीं। उदाहरण हर जगह और कहीं भी जा सकते हैं जहां वे पहुंच सकते हैं। भविष्य में हास्केल के संभावित समायोजन के बारे में: शायद। टाइपक्लास के बजाए अपने स्वयं के तंत्र के उपयोग के संबंध में: हाँ। –

उत्तर

11

प्रस्तावित विस्तार में मेरी समस्या this previous answer में प्रदर्शित की गई एक ही समस्या है; आप दो उदाहरणों के साथ दो Map एस बनाने के लिए स्थानीय उदाहरणों का उपयोग कर सकते हैं लेकिन अलग-अलग Ord उदाहरण, जिससे सभी आविष्कारक क्रैश हो रहे हैं।

हालांकि, reflection पैकेज आप इस तरह के एक ModN प्रकार को परिभाषित करने की अनुमति देता है: यदि आप एक Reifies बाधा के साथ एक उदाहरण परिभाषित करते हैं, और के लिए एक विशेष nreify साथ उदाहरण को सक्रिय करें। (मेरा मानना ​​है कि implicit parameters यह भी संभव बना देगा, लेकिन उस एक्सटेंशन का शायद ही कभी उपयोग किया जाता है।)

संबंधित मुद्दे