क्या एक टाइपक्लास बनाना संभव है जो अब नए सदस्यों को स्वीकार नहीं कर सकता (शायद मॉड्यूल सीमाओं का उपयोग करके)? मैं एक पूर्ण आवृत्ति परिभाषा के लिए आवश्यक एक फ़ंक्शन को निर्यात करने से इंकार कर सकता हूं, लेकिन अगर कोई अमान्य उदाहरण उत्पन्न करता है तो केवल रनटाइम त्रुटि में परिणाम होता है। क्या मैं इसे संकलित समय त्रुटि बना सकता हूं?बंद प्रकार के वर्ग
उत्तर
मुझे विश्वास है कि उत्तर एक योग्य हां है, जो आप प्राप्त करने की कोशिश कर रहे हैं उसके आधार पर।
आप टाइप क्लास नामों के नामों को निर्यात करते समय टाइप इंटरफ़ेस मॉड्यूल से टाइप क्लास नाम को निर्यात करने से बच सकते हैं। तब कोई भी कक्षा का उदाहरण नहीं दे सकता क्योंकि कोई भी इसका नाम नहीं दे सकता!
उदाहरण:
module Foo (
foo,
bar
) where
class SecretClass a where
foo :: a
bar :: a -> a -> a
instance SecretClass Int where
foo = 3
bar = (+)
नकारात्मक पक्ष यह है कि कोई भी या तो एक बाधा के रूप में अपने वर्ग के साथ एक प्रकार लिख सकते हैं। यह पूरी तरह से लोगों को उन कार्यों को लिखने से रोकता है जिनके पास ऐसा प्रकार होगा, क्योंकि संकलक अभी भी अनुमान प्रकार में सक्षम होगा। लेकिन यह बहुत परेशान होगा।
आप एक सुपर-क्लास के रूप में अपनी "बंद" कक्षा के साथ, एक और खाली प्रकार वर्ग प्रदान करके नकारात्मक पक्ष को कम कर सकते हैं। आप अपनी मूल कक्षा के प्रत्येक उदाहरण को उप-वर्ग का एक उदाहरण भी बनाते हैं, और आप उप वर्ग (सभी प्रकार के वर्ग कार्यों के साथ) निर्यात करते हैं, लेकिन सुपर क्लास नहीं। (स्पष्टता के लिए आपको अपने द्वारा खुलासा किए जाने वाले सभी प्रकारों में "गुप्त" की बजाय "सार्वजनिक" वर्ग का उपयोग करना चाहिए, लेकिन मेरा मानना है कि यह किसी भी तरह से काम करता है)।
उदाहरण:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Foo (
PublicClass,
foo,
bar
) where
class SecretClass a where
foo :: a
bar :: a -> a -> a
class SecretClass a => PublicClass a
instance SecretClass Int where
foo = 3
bar = (+)
instance SecretClass a => PublicClass a
आप एक्सटेंशन के बिना कर सकते हैं यदि आप मैन्युअल SecretClass
के प्रत्येक उदाहरण के लिए PublicClass
का एक उदाहरण घोषित करने के लिए तैयार हैं।
अब ग्राहक कोड PublicClass
का उपयोग प्रकार वर्ग की कमी लिखने के लिए कर सकते हैं, लेकिन PublicClass
के प्रत्येक उदाहरण एक ही प्रकार के लिए SecretClass
का एक उदाहरण आवश्यकता है, और कोई रास्ता नहीं के साथ SecretClass
का एक नया उदाहरण घोषित करने के लिए कोई भी किसी भी अधिक प्रकार के उदाहरणों कर सकते हैं PublicClass
का।
यह सब नहीं है, तो आप कक्षा को "बंद" के रूप में मानने के लिए संकलक की क्षमता प्राप्त करते हैं। यह अभी भी अस्पष्ट प्रकार चर के बारे में शिकायत करेगा जिसे "बंद" का एकमात्र दृश्यमान उदाहरण चुनकर हल किया जा सकता है।
शुद्ध राय: यह आमतौर पर एक डरावना नाम जो सब कुछ का निर्यात करता है, ताकि आप परीक्षण/डिबगिंग के लिए इसे प्राप्त कर सकते हैं के साथ एक अलग आंतरिक मॉड्यूल के लिए एक अच्छा विचार है, एक इंटरफेस मॉड्यूल है कि आयात के साथ है आंतरिक मॉड्यूल और केवल उन्हीं चीज़ों को निर्यात करता है जिन्हें आप निर्यात करना चाहते हैं।
मुझे लगता है कि एक्सटेंशन के साथ कोई नया ओवरलैपिंग उदाहरण घोषित कर सकता है। जैसे अगर आपने [a]
के लिए एक उदाहरण प्रदान किया है, तो PublicClass
का [Int]
के लिए कोई नया उदाहरण घोषित कर सकता है, जो SecretClass
के उदाहरण पर [a]
के उदाहरण पर पिगबैक करेगा।लेकिन दिया गया है कि PublicClass
में कोई फ़ंक्शन नहीं है और वे SecretClass
का एक उदाहरण नहीं लिख सकते हैं, मैं नहीं देख सकता कि इसके साथ बहुत कुछ किया जा सकता है।
हालांकि कोई भी अभी भी 'पब्लिक क्लास' के उदाहरण बना सकता है, और जब मुझे नहीं पता कि कौन सी टेलिसी हासिल करने की कोशिश कर रहा था, तो मैं अभी इस परिदृश्य के बारे में सोच नहीं सकता हूं, जहां इसका 'सिरेक्ट क्लास' निर्यात करने के समान प्रभाव नहीं होंगे। पहले स्थान पर। क्या आप? – firefrorefiddle
@ माइक हार्टल नहीं, आप उन प्रकार के लिए 'पब्लिक क्लास' के उदाहरण नहीं बना सकते हैं जो पहले से ही 'गुप्त क्लास' के उदाहरण नहीं हैं। आपको एक इंस्टेंस घोषणा के सुपरक्लास से उत्पन्न होने वाली कोई घटना नहीं है (Foo.SecretClass Bool) संभावित फिक्स: (Foo.SecretClass Bool) के लिए एक उदाहरण घोषणा जोड़ें। और आप उस उदाहरण को जोड़ नहीं सकते हैं, क्योंकि 'SecretClass' मॉड्यूल के बाहर कहीं भी दायरे में नहीं है। – Ben
आह! मेरी गलती। मैंने इसे 'इंस्टेंस (SecretClass ए) => पब्लिक क्लास ए' के साथ गलत समझा। – firefrorefiddle
GHC 7.8.1, closed type families के बाद घोषित किया जा सकता है, और मैं उन्हें की मदद से लगता है, और ConstraintKinds
, तो आप ऐसा कर सकते हैं:
type family SecretClass (a :: *) :: Constraint where
SecretClass Int =()
SecretClass a
की कोई समस्या है, एक प्रकार वर्ग के बराबर रूपों, और चूंकि परिवार को किसी के द्वारा विस्तारित नहीं किया जा सकता है, इसलिए "वर्ग" के किसी अन्य उदाहरण को परिभाषित नहीं किया जा सकता है।
(यह वास्तव में, बस अटकलें के बाद से मैं यह परीक्षण नहीं कर सकते, लेकिन this interesting link में कोड यह देखो की तरह यह काम करेगा बनाता है।)
साफ विचार, धन्यवाद। –
पैट्रिक बह्र के पेपर के दोनों लिंक 404 हैं। बहरी की साइट से [यह लिंक] (http://bahr.io/pubs/files/serrano15haskell-paper.pdf) आज़माएं। –
आप एक डेटा घोषणा में typeclass refactor सकता है (उपयोग रिकॉर्ड वाक्य रचना) जिसमें आपके टाइपक्लास के सभी फ़ंक्शन शामिल हैं। उदाहरणों की एक निश्चित सीमित सूची आपको लगता है कि आपको किसी भी वर्ग की आवश्यकता नहीं है।
यह निश्चित रूप से यह है कि संकलक वैसे भी आपके वर्ग के दृश्यों को व्यवहार कर रहा है।
यह आपको अपने डेटा प्रकार के कार्यों के रूप में उदाहरणों की सूची निर्यात करने की अनुमति देगा, और आप उन्हें निर्यात कर सकते हैं लेकिन डेटा प्रकार के लिए निर्माता नहीं। इसी तरह, आप एक्सेसर फ़ंक्शंस के निर्यात को प्रतिबंधित कर सकते हैं, और केवल उस इंटरफ़ेस को निर्यात कर सकते हैं जिसे आप वास्तव में चाहते हैं।
यह ठीक काम करता है क्योंकि डेटा प्रकार मॉड्यूल-सीमा-पार करने वाली खुली दुनिया धारणा के अधीन नहीं हैं टाइपक्लास हैं।
कभी-कभी टाइप सिस्टम जटिलता जोड़ना चीजों को कठिन बनाता है।
आप बंद प्रकार के परिवारों के माध्यम से बंद प्रकार के वर्गों को एन्कोड कर सकते हैं, जिन्हें अनिवार्य रूप से संबंधित प्रकार के परिवारों के रूप में एन्कोड किया जा सकता है। इस समाधान की कुंजी यह है कि किसी संबंधित प्रकार के परिवार के उदाहरण एक प्रकार के वर्ग के उदाहरण के अंदर होते हैं, और प्रत्येक मोनोमोर्फिक प्रकार के लिए केवल एक प्रकार का वर्ग उदाहरण हो सकता है।
ध्यान दें कि यह दृष्टिकोण मॉड्यूल सिस्टम से स्वतंत्र है। मॉड्यूल सीमाओं पर भरोसा करने के बजाय, हम एक स्पष्ट सूची प्रदान करते हैं कि कौन से उदाहरण कानूनी हैं। इसका मतलब यह है कि, एक तरफ, कानूनी उदाहरण कई मॉड्यूल या यहां तक कि संकुलों पर फैल सकते हैं, और दूसरी ओर, हम एक ही मॉड्यूल में अवैध उदाहरण प्रदान नहीं कर सकते हैं।
इस जवाब के लिए, मुझे लगता है कि हम निम्नलिखित वर्ग को बंद करना चाहते हैं ताकि इसमें प्रकार Int
और Integer
के लिए instantiated जा सकता है लेकिन अन्य प्रकार के लिए नहीं:
-- not yet closed
class Example a where
method :: a -> a
सबसे पहले, हम एक की जरूरत है बंद प्रकार परिवारों को एन्कोडिंग के लिए छोटे प्रकार के ढांचे को संबंधित प्रकार के परिवारों के रूप में।
{-# LANGUAGE TypeFamilies, EmptyDataDecls #-}
class Closed c where
type Instance c a
पैरामीटर c
प्रकार परिवार और पैरामीटर a
के नाम के लिए खड़ा प्रकार परिवार का सूचकांक है। c
का परिवार उदाहरण a
के लिए Instance c a
के रूप में एन्कोड किया गया है। चूंकि c
एक वर्ग पैरामीटर भी है, इसलिए c
के सभी पारिवारिक उदाहरणों को एक वर्ग के उदाहरण घोषणा में एक साथ दिया जाना है।
अब, हम एन्कोड करने के लिए कि Int
और Integer
Ok
हैं, और अन्य सभी प्रकार के नहीं हैं एक बंद प्रकार परिवार MemberOfExample
परिभाषित करने के लिए इस ढांचे का उपयोग करें।
data MemberOfExample
data Ok
instance Closed MemberOfExample where
type Instance MemberOfExample Int = Ok
type Instance MemberOfExample Integer = Ok
अंत में, हम हमारे Example
की एक सुपर क्लास contraint में इस बंद प्रकार परिवार का उपयोग करें।
class Instance MemberOfExample a ~ Ok => Example a where
method :: a -> a
हम Int
और Integer
हमेशा की तरह के लिए मान्य उदाहरणों परिभाषित कर सकते हैं।
instance Example Int where
method x = x + 1
instance Example Integer where
method x = x + 1
लेकिन हम Int
और Integer
के अलावा अन्य प्रकार के लिए अमान्य उदाहरणों को परिभाषित नहीं कर सकते हैं।
-- GHC error: Couldn't match type `Instance MemberOfExample Float' with `Ok'
instance Example Float where
method x = x + 1
और हम वैध प्रकारों के सेट को भी विस्तारित नहीं कर सकते हैं।
-- GHC error: Duplicate instance declarations
instance Closed MemberOfExample where
type Instance MemberOfExample Float = Ok
-- GHC error: Associated type `Instance' must be inside a class instance
type instance Instance MemberOfExample Float = Ok
दुर्भाग्यवश, हम निम्न फर्जी उदाहरण लिख सकते हैं:
-- Unfortunately accepted
instance Instance MemberOfExample Float ~ Ok => Example Float where
method x = x + 1
लेकिन चूंकि हम समानता बाधा का निर्वहन करने में सक्षम नहीं होगा, मुझे नहीं लगता कि हम कभी भी कुछ भी करने के लिए उपयोग कर सकते हैं करते हैं। उदाहरण के लिए, निम्न को अस्वीकार कर दिया गया है:
-- Couldn't match type `Instance MemberOfExample Float' with `Ok'
test = method (pi :: Float)
यह @ बेन के उत्तर की तरह बहुत प्रतीत होता है। क्या आप विस्तार से बता सकते हैं कि वे कैसे भिन्न हैं? –
@tel: सबसे महत्वपूर्ण अंतर यह प्रतीत होता है कि यह दृष्टिकोण मॉड्यूल सिस्टम से स्वतंत्र है। मैंने इसे इंगित करने के उत्तर में एक पैराग्राफ जोड़ा। – Toxaris
जब सब आपको लगता है कि आप में रुचि रखते उदाहरणों में से एक enumertated सेट कर रहे हैं, तो यह चाल मदद कर सकता है:
class (Elem t '[Int, Integer, Bool] ~ True) => Closed t where
type family Elem (t :: k) (ts :: [k]) :: Bool where
Elem a '[] = False
Elem a (a ': as) = True
Elem a (b ': bs) = Elem a bs
instance Closed Int
instance Closed Integer
-- instance Closed Float -- ERROR
- 1. वर्ग बंद
- 2. पीएचपी, बंद वर्ग
- 3. css3 nth प्रकार के वर्ग
- 4. जीएचसी एक प्रकार के वर्ग
- 5. प्रकार वर्ग और आश्रित प्रकार
- 6. वर्ग के अपने प्रकार के स्थिर वर्ग के सदस्य
- 7. प्रतिबंधित बंद प्रकार परिवार
- 8. एक वर्ग के वर्ग प्रकार बदलने के बाद सम्मिलित डेटा
- 9. वर्ग प्रकार के वेक्टर के साथ आगे की घोषणा - अपूर्ण वर्ग प्रकार के सूचक को
- 10. जावा जेनेरिक वर्ग - प्रकार
- 11. मल्टीपार्म प्रकार वर्ग
- 12. अज्ञात प्रकार नाम वर्ग
- 13. विभिन्न वर्ग प्रकार
- 14. सामान्य रूपांतरण प्रकार वर्ग
- 15. कुछ वर्ग प्रकार
- 16. अभिव्यक्ति वर्ग प्रकार
- 17. बंद प्रकार के परिवारों पर बाधाएं?
- 18. बंद प्रकार के परिवार और अजीब फ़ंक्शन प्रकार
- 19. त्रुटि C2011: '': 'इस प्रकार वर्ग' प्रकार परिभाषा
- 20. प्रकार वर्ग "FlexibleInstances" के विषय में समस्या
- 21. सी ++ वर्ग प्रकार तर्क के रूप में
- 22. LINQ - समूह विशिष्ट प्रकार के वर्ग
- 23. एक विशिष्ट प्रकार के सामान्य वर्ग
- 24. जेनेरिक वर्ग कि दो प्रकार के
- 25. टेस्ट अगर वस्तु गूगल बंद वर्ग ढांचे
- 26. क्या ग्रोवी बंद एक अमूर्त वर्ग
- 27. वर्ग [_] प्रकार पर पैटर्न मिलान?
- 28. सारणी वर्ग सबसे व्युत्पन्न प्रकार
- 29. jQuery: वर्ग और इनपुट प्रकार
- 30. जेनिक्स - ओपन और बंद निर्मित प्रकार
ये जवाब हैं आप सभी महान धन्यवाद everone! –