2011-01-27 10 views
6

मैं कई असंगत बनाना चाहता हूं, लेकिन अन्यथा बराबर, डेटाटाइप। जो है, मैंक्या मैं हैस्केल में सिंगलटन प्रकारों के बारे में सोच रहा हूं और उपयोग कर रहा हूं?

bar :: (Foo a) -> (Foo a) -> (Foo a) 

इस तरह के रूप में भी कार्य वास्तव में क्या a है के बारे में देखभाल के बिना एक पैरामिट्रीकृत प्रकार Foo a करना चाहते हैं, और। आगे स्पष्ट करने के लिए, मैं मेरे

x :: Foo Int 
y :: Foo Char 
bar x y 

करने से रोकने के लिए जब मैं एक ही समय में वास्तव में परवाह नहीं है के बारे में Int और Char (मैं केवल परवाह कि वे एक ही नहीं कर रहे हैं) प्रकार प्रणाली चाहते हैं ।

मेरे वास्तविक कोड में मेरे पास एक दी गई अंगूठी पर बहुपद के लिए एक प्रकार है। मैं वास्तव में परवाह नहीं करता कि indeterminates क्या हैं, जब तक कि प्रकार प्रणाली मुझे बहुपद के साथ एक बहुपद जोड़ना बंद कर देता है। जो विशेष रूप से अंगूठी के बारे में दिए गए बहुपद खत्म हो गया है, क्योंकि मैं देखभाल कर अब तक मैं एक typeclass Indeterminate बनाने, और के रूप में

data (Ring a, Indeterminate b) => Polynomial a b 

यह दृष्टिकोण मेरी बहुपद प्रकार parameterizing द्वारा इस समाधान कर लिया है Ring भाग के लिए पूरी तरह से प्राकृतिक महसूस करता है । Indeterminate भाग के लिए यह बहुत समझा जाता है, जैसा कि नीचे दिया गया है।

उपर्युक्त दृष्टिकोण ठीक काम करता है, लेकिन माना जाता है। विशेष रूप से इस भाग:

class Indeterminate a where 
    indeterminate :: a 

data T = T 

instance Indeterminate T where 
    indeterminate = T 

data S = S 

instance Indeterminate S where 
    indeterminate = S 

(और शायद कुछ और अनिश्चितता के लिए)। यह अजीब और गलत लगता है। अनिवार्य रूप से मैं यह मांगने की कोशिश कर रहा हूं कि Indeterminate के उदाहरण सिंगलेट बनें (this sense में)। अजीबता की भावना एक संकेतक है कि मैं इस गलत तरीके से हमला कर सकता हूं। एक और तथ्य यह है कि मैं अपने Polynomial a b एस के बहुत सारे एनोटेट करने के लिए समाप्त होता हूं क्योंकि वास्तविक प्रकार b अक्सर अनुमानित नहीं किया जा सकता है (यह अजीब नहीं है, लेकिन फिर भी परेशान है)।

कोई सुझाव? क्या मुझे बस ऐसा करने पर रोकना चाहिए, या क्या मुझे कुछ याद आ रहा है?

पीएस: अगर मैं तुरंत जवाब नहीं देता या जवाब नहीं देता तो नाराज न हों। मैं कुछ दिनों के लिए वापस जांचने में असमर्थ हूं।

+0

क्या बहुपद मॉडलिंग को अंगूठी के तत्वों के अनुक्रम या उदाहरण के लिए कुछ (उदाहरण के लिए आंशिक रकम के अनुक्रम) के रूप में मॉडलिंग नहीं करने का कोई अच्छा कारण है? –

+0

ठीक है, मैं यहाँ थोड़ा सा खो गया हूँ। मुझे समझ में नहीं आता कि आपको 'अनिश्चितता' क्यों चाहिए। यदि आप बस दो बीएस लागू करना चाहते हैं, तो इसे टाइप हस्ताक्षर में छोड़ दें, और यही वह है? – sclv

+0

@Alexandre सी .: मैं यह कर रहा हूँ। लेकिन मैं टाइप हस्ताक्षर को अर्थहीन बनाना चाहता हूं, कहें, "2 + 5t" से "6s" जोड़ें। अंगूठी तत्वों के अनुक्रमों के रूप में बहुपद के साथ, प्रकार प्रणाली (सही ढंग से) मुझे एक अंगूठी में गुणांक के साथ बहुपद जोड़ना बंद कर देता है जिसमें एक दूसरे के गुणांक के साथ होता है, लेकिन यह अनिश्चितता पर अंतर नहीं करता है। अब, ज़ाहिर है, मुझे वास्तव में अनिश्चितता की आवश्यकता है या नहीं, यह एक बहुत ही वैध सवाल है :-) – gspr

उत्तर

7

सबसे पहले, मैं इस यकीन नहीं है:

data (Ring a, Indeterminate b) => Polynomial a b 

... क्या कर रही है कि तुम क्या यह उम्मीद करते हैं। data पर संदर्भ बहुत उपयोगी नहीं हैं - कुछ कारणों से the discussion here देखें, क्यों उनमें से अधिकतर राशि आपको अतिरिक्त अतिरिक्त गारंटी प्रदान किए बिना अतिरिक्त एनोटेशन जोड़ने के लिए मजबूर करती है।

दूसरा, क्या आप वास्तव में यह सुनिश्चित करने के अलावा "अनिश्चित" पैरामीटर की परवाह करते हैं कि प्रकार अलग रखा गया है? उस तरह की चीज करने का एक सुंदर मानक तरीका है जिसे phantom types कहा जाता है - अनिवार्य रूप से, प्रकार के कन्स्ट्रक्टर में पैरामीटर जो डेटा कन्स्ट्रक्टर में उपयोग नहीं किए जाते हैं। आप इस्तेमाल करेंगे कभी नहीं या प्रेत प्रकार के एक मूल्य की जरूरत है, तो कार्य के रूप में बहुरूपी आप चाहते हैं के रूप में हो सकता है, उदाहरण के लिए:

data Foo a b = Foo b 

foo :: Foo a b -> Foo a b 
foo (Foo x) = Foo x 

bar :: Foo a c -> Foo b c 
bar (Foo x) = Foo x 

baz :: Foo Int Int -> Foo Char Int -> Foo() Int 
baz (Foo x) (Foo y) = Foo $ x + y 

जाहिर है इस एनोटेशन की आवश्यकता होती है, लेकिन केवल स्थानों पर जहां आप जानबूझकर प्रतिबंध जोड़ रहे हैं में ।अन्यथा, अनुमान सामान्य रूप से प्रेत प्रकार पैरामीटर के लिए काम करेगा।

ऐसा लगता है कि उपरोक्त दृष्टिकोण आप जो कर रहे हैं उसके लिए पर्याप्त होना चाहिए - सिंगलटन प्रकारों वाला व्यवसाय अधिक जटिल प्रकार-स्तर की सामग्री और नियमित मूल्य-स्तर की गणना के बीच अंतर को ब्रिजिंग करने के बारे में है मूल्यों के लिए प्रॉक्सी टाइप करें। यह वैक्टरों को उन प्रकारों के साथ चिह्नित करने के लिए उपयोगी हो सकता है जो उनके आधार को इंगित करते हैं, या भौतिक इकाइयों के साथ संख्यात्मक मानों को चिह्नित करते हैं - दोनों मामलों में जहां एनोटेशन का "अनिश्चित नामक एक्स" की तुलना में अधिक अर्थ होता है।

+1

'-XEmptyDataDecls' के साथ आप इसे बना सकते हैं ताकि आपके" मार्कर "प्रकारों में कोई रनटाइम प्रतिनिधित्व न हो, उदाहरण के लिए। 'डेटा टी ', और फिर एक नई लाइन और अपना कोड contine। यह कहता है कि 'टी' कोई रचनाकार नहीं है, और इस प्रकार यह वास्तव में केवल टाइप सिस्टम के लिए कुछ है। – luqui

+0

धन्यवाद! मुझे लगता है कि आपको वही मिला जो मैं पूछ रहा था और सोच रहा था। मुझे प्रेत के प्रकारों के बारे में पता नहीं था, इसलिए मुझे सिखाने के लिए धन्यवाद। जब सिंगलेटन का वास्तव में उपयोग किया जाता है, तो स्पष्टीकरण भी बहुत प्रबुद्ध होता है, और जिस चीज में मुझे समस्या हो रही थी, उसके मूल के लिए सही हो जाता है (वास्तव में, क्या आपने मेरा दिमाग पढ़ा?)। (एक तरफ ध्यान दें: मुझे पता है कि 'डेटा' परिभाषाओं पर संदर्भ उपयोगी नहीं हैं - मैं कोड लिखते समय अपनी सोच में सहायता के लिए उनका उपयोग करता हूं, लेकिन बाद में उन्हें बाहर ले जाता हूं। मुझे पूछने से पहले उन्हें हटा देना चाहिए था)। – gspr

+1

@gspr: किसी बिंदु पर आप जीएडीटी और संबंधित भाषा एक्सटेंशन के बारे में पढ़ना चाह सकते हैं - उनके द्वारा प्रदान की जाने वाली अभिव्यक्तित्मक शक्ति कुछ ऐसी चीज की तरह लगती है जो आपको उपयोगी हो सकती है, जो अन्य परिभाषाओं (डेटा के साथ) डेटा परिभाषाओं पर संदर्भित करती है जो वास्तव में सार्थक हैं। –

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