haskell - हास्केल/जीएचसी में 'फॉरल' कीवर्ड क्या करता है?




syntax types (6)

क्या कोई स्पष्ट रूप से स्पष्ट, सादे अंग्रेजी में संपूर्ण कीवर्ड को समझा सकता है (या, यदि यह कहीं मौजूद है, तो मुझे स्पष्ट स्पष्टीकरण की ओर इशारा करते हैं) जो मुझे नहीं लगता कि मैं शब्दकोष में घुसपैठ कर रहा हूं?

मैं सिर्फ हास्केल और इसके प्रकार के सिस्टम के संदर्भ में केवल अर्थ और शायद अंतिम रूप से आवेदन करने की कोशिश करने और समझाने जा रहा हूं।

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

                CONSTRAINTS LIBERATE, LIBERTIES CONSTRAIN

निम्नलिखित स्पष्टीकरण के साथ आगे बढ़ने के लिए इस कथन को पचाने और विश्वास करने के लिए बहुत महत्वपूर्ण है, इसलिए मैं आपको वार्ता (कम से कम इसके कुछ हिस्सों) देखने के लिए आग्रह करता हूं।

अब एक बहुत ही आम उदाहरण है, हास्केल प्रकार प्रणाली की अभिव्यक्ति दिखाते हुए यह प्रकार हस्ताक्षर है:

foo :: a -> a

ऐसा कहा जाता है कि इस प्रकार के हस्ताक्षर दिए गए, केवल एक ही कार्य है जो इस प्रकार को संतुष्ट कर सकता है और यह identity कार्य है या अधिक लोकप्रिय रूप से ज्ञात id

हास्केल सीखने के शुरुआती चरणों में, मैंने हमेशा निम्न कार्यों को सोचा:

foo 5 = 6

foo True = False

वे दोनों उपरोक्त प्रकार के हस्ताक्षर को पूरा करते हैं, तो हास्केल लोगों का दावा क्यों है कि यह अकेला id है जो प्रकार हस्ताक्षर को संतुष्ट करता है?

ऐसा इसलिए है क्योंकि प्रकार हस्ताक्षर में छिपी हुई एक निहित है। वास्तविक प्रकार है:

id :: forall a. a -> a

तो, अब हम कथन पर वापस आएं: बाधाएं मुक्त, स्वतंत्रता बाधाएं

टाइप सिस्टम को अनुवाद करना, यह कथन बन जाता है:

प्रकार के स्तर पर एक बाधा, शब्द स्तर पर एक स्वतंत्रता बन जाती है

तथा

प्रकार के स्तर पर एक स्वतंत्रता, शब्द स्तर पर एक बाधा बन जाती है

आइए पहले कथन को साबित करने का प्रयास करें:

प्रकार के स्तर पर एक बाधा ..

तो हमारे प्रकार हस्ताक्षर पर एक बाधा डालना

foo :: (Num a) => a -> a

शब्द स्तर पर एक स्वतंत्रता बन जाती है , इन सभी को लिखने के लिए हमें स्वतंत्रता या लचीलापन देता है

foo 5 = 6
foo 4 = 2
foo 7 = 9
...

किसी भी अन्य टाइपक्लास आदि के साथ बाधा डालकर भी देखा जा सकता है

तो अब इस प्रकार के हस्ताक्षर क्या हैं: foo :: (Num a) => a -> a अनुवाद है:

∃a , st a -> a, ∀a ∈ Num

इसे अस्तित्वत्मक मात्रा के रूप में जाना जाता है, जिसका अनुवाद करने के लिए कुछ उदाहरण मौजूद हैं जिसके लिए एक प्रकार का काम किया जाता है जब किसी प्रकार का कुछ प्रकार a रिटर्न देता है, और वे सभी उदाहरण संख्याओं के सेट से संबंधित होते हैं।

इसलिए हम एक बाधा जोड़ सकते हैं (जो कि संख्याओं के सेट से संबंधित होना चाहिए), शब्द स्तर को कई संभावित कार्यान्वयन के लिए मुक्त करता है।

अब दूसरे कथन में आ रहा है और वह जो वास्तव में forall की व्याख्या forall :

प्रकार के स्तर पर एक स्वतंत्रता, शब्द स्तर पर एक बाधा बन जाती है

तो अब हम इस प्रकार के कार्य को स्तर स्तर पर मुक्त करते हैं:

foo :: forall a. a -> a

अब यह अनुवाद करता है:

∀a , a -> a

जिसका अर्थ है कि इस प्रकार के हस्ताक्षर का कार्यान्वयन ऐसा होना चाहिए कि यह सभी परिस्थितियों के लिए a -> a है।

तो अब यह शब्द स्तर पर हमें बाधा शुरू कर देता है। हम अब लिख नहीं सकते हैं

foo 5 = 7

क्योंकि अगर हम एक Bool रूप में डालते हैं तो यह कार्यान्वयन संतुष्ट नहीं होगा। a Char या एक [Char] या एक कस्टम डेटाटाइप हो सकता है। सभी परिस्थितियों में इसे समान प्रकार के कुछ वापस करना चाहिए। प्रकार के स्तर पर यह स्वतंत्रता सार्वभौमिक मात्रा के रूप में जाना जाता है और यह एकमात्र कार्य है जो इसे संतुष्ट कर सकता है

foo a = a

जिसे आमतौर पर identity समारोह के रूप में जाना जाता है

इसलिए forall स्तर पर एक liberty है, जिसका वास्तविक उद्देश्य किसी विशेष कार्यान्वयन के लिए शब्द स्तर को constrain करना है।

मुझे यह समझना शुरू हो रहा है कि तथाकथित "अस्तित्वहीन प्रकारों" में इस प्रकार के कीवर्ड का उपयोग कैसे किया जाता है:

data ShowBox = forall s. Show s => SB s

यह केवल एक सबसेट है, हालांकि, कैसे उपयोग किया जाता है और मैं इस तरह की चीजों में अपने दिमाग को अपने उपयोग के आसपास लपेट नहीं सकता हूं:

runST :: forall a. (forall s. ST s a) -> a

या समझाओ कि ये अलग क्यों हैं:

foo :: (forall a. a -> a) -> (Char,Bool)
bar :: forall a. ((a -> a) -> (Char, Bool))

या पूरे RankNTypes सामान ...

मैं अकादमिक वातावरण में सामान्य भाषा की तरह स्पष्ट, शब्दकोष मुक्त अंग्रेजी पसंद करते हैं। अधिकांश स्पष्टीकरण जिन्हें मैं इस पर पढ़ने का प्रयास करता हूं (जिन्हें मैं खोज इंजन के माध्यम से ढूंढ सकता हूं) में ये समस्याएं हैं:

  1. वे अपूर्ण हैं। वे इस खोजशब्द (जैसे "अस्तित्वहीन प्रकार") के उपयोग के एक हिस्से को समझाते हैं, जो मुझे तब तक खुश महसूस करता है जब तक कि मैं इसे कोड को पढ़ता हूं जो इसे पूरी तरह से अलग तरीके से उपयोग करता है (जैसे runST , foo और bar ऊपर)।
  2. वे अनुमानों से घिरे हुए हैं कि मैंने इस सप्ताह में असतत गणित, श्रेणी सिद्धांत या अमूर्त बीजगणित की किसी भी शाखा में नवीनतम पढ़ा है। (यदि मैंने कभी भी "कार्यान्वयन के विवरण के लिए जो कुछ भी कागज़ से परामर्श नहीं किया है" शब्द कभी नहीं पढ़ा है, तो यह बहुत जल्द होगा।)
  3. वे ऐसे तरीकों से लिखे गए हैं जो कथित रूप से मुड़कर और फ्रैक्चर किए गए व्याकरण और अर्थशास्त्र में भी सरल अवधारणाओं को बदल देते हैं।

इसलिए...

वास्तविक प्रश्न पर। क्या कोई स्पष्ट रूप से स्पष्ट, सादे अंग्रेजी में forall कीवर्ड को समझा सकता है (या, यदि यह कहीं मौजूद है, तो मुझे स्पष्ट स्पष्टीकरण की ओर इशारा करते हैं) जो मुझे नहीं लगता कि मैं forall में forall कर रहा हूं?

जोड़ने के लिए संपादित:

नीचे उच्च गुणवत्ता वाले लोगों से दो स्टैंड-आउट उत्तर थे, लेकिन दुर्भाग्य से मैं केवल एक को सर्वश्रेष्ठ चुन सकता हूं। नॉर्मन का जवाब विस्तृत और उपयोगी था, जिस तरह से चीजों को समझाते हुए दिखाया गया था कि कुछ सैद्धांतिक आधारभूत सिद्धांतों को forall और साथ ही साथ मुझे इसके कुछ व्यावहारिक प्रभाव भी दिखाए गए थे। Yairchu के उत्तर में किसी भी क्षेत्र का उल्लेख नहीं किया गया है (स्कॉप्ड प्रकार चर) और कोड और जीएचसीआई सत्र के साथ सभी अवधारणाओं को सचित्र किया। क्या मैं सबसे अच्छा चयन करना संभव था, मैं चाहता था। दुर्भाग्य से मैं और दोनों उत्तरों को बारीकी से देखकर नहीं कर सकता, मैंने फैसला किया है कि चित्रकारी कोड और संलग्न स्पष्टीकरण के कारण यैचु का नॉर्मन का थोड़ा सा किनारा है। हालांकि, यह थोड़ा सा अनुचित है, क्योंकि वास्तव में मुझे इस बात को समझने के लिए दोनों उत्तरों की आवश्यकता है कि जब मैं इसे एक प्रकार के हस्ताक्षर में देखता हूं तो मुझे डर की बेहोश भावना से नहीं छोड़ता है।


क्या कोई स्पष्ट रूप से स्पष्ट, सादे अंग्रेजी में संपूर्ण कीवर्ड को समझा सकता है?

नहीं। (ठीक है, शायद डॉन स्टीवर्ट कर सकते हैं।)

यहां एक सरल, स्पष्ट स्पष्टीकरण या कुल के लिए forall :

  • यह एक क्वांटिफायर है। सार्वभौमिक या अस्तित्वत्मक क्वांटिफायर देखने के लिए आपके पास कम-से-कम तर्क (पूर्वानुमान कैलकुस) होना चाहिए। यदि आपने कभी अनुमानित कैलकुंस नहीं देखा है या क्वांटिफ़ायर के साथ सहज नहीं हैं (और मैंने पीएचडी क्वालीफाइंग परीक्षाओं के दौरान छात्रों को देखा है जो आरामदायक नहीं हैं), तो आपके लिए, कुल forall कोई आसान स्पष्टीकरण नहीं है।

  • यह एक प्रकार क्वांटिफायर है। यदि आपने सिस्टम एफ नहीं देखा है और कुछ अभ्यास लिखने वाले पॉलीमोर्फिक प्रकार प्राप्त कर चुके हैं, तो आप पूरी तरह उलझन में पाएंगे। हास्केल या एमएल के साथ अनुभव पर्याप्त नहीं है, क्योंकि आम तौर पर ये भाषाएं forall प्रकारों से forall को छोड़ देती हैं। (मेरे दिमाग में, यह एक भाषा-डिजाइन गलती है।)

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

    यदि आप टाइप आइसोमोर्फिज्म के विचार से सहज नहीं हैं, या यदि आपके पास टाइप आइसोमोर्फिज्म के बारे में सोचने का कोई अभ्यास नहीं है, तो यह का उपयोग आपको forall करने जा रहा है।

  • जबकि forall की सामान्य अवधारणा हमेशा एक ही होती है (एक प्रकार परिवर्तनीय पेश करने के लिए बाध्यकारी), विभिन्न उपयोगों का विवरण महत्वपूर्ण रूप से भिन्न हो सकता है। अनौपचारिक अंग्रेजी विविधताओं को समझाने के लिए एक बहुत अच्छा उपकरण नहीं है। वास्तव में समझने के लिए कि क्या हो रहा है, आपको कुछ गणित की आवश्यकता है। इस मामले में प्रासंगिक गणित बेंजामिन पिएर्स के प्रारंभिक पाठ प्रकार और प्रोग्रामिंग भाषाओं में पाया जा सकता है, जो एक बहुत अच्छी किताब है।

आपके विशेष उदाहरणों के लिए,

  • runST को आपके सिर को चोट runST चाहिए । उच्च-रैंक प्रकार (तीर के बाईं ओर के लिए) जंगली में शायद ही कभी पाए जाते हैं। मैं आपको उस पेपर को पढ़ने के लिए प्रोत्साहित करता हूं जो runST प्रस्तुत runST : "आलसी कार्यात्मक राज्य थ्रेड" । यह वास्तव में एक अच्छा पेपर है, और यह आपको विशेष रूप से runST प्रकार और सामान्य रूप से उच्च रैंक प्रकारों के लिए एक बेहतर अंतर्ज्ञान प्रदान करेगा। स्पष्टीकरण कई पेज लेता है, यह बहुत अच्छा किया गया है, और मैं इसे यहां संयोजित करने की कोशिश नहीं कर रहा हूं।

  • विचार करें

    foo :: (forall a. a -> a) -> (Char,Bool)
    bar :: forall a. ((a -> a) -> (Char, Bool))
    

    अगर मैं bar कॉल करता हूं, तो मैं बस किसी भी प्रकार का चयन कर सकता हूं जिसे मैं पसंद करता हूं, और मैं इसे टाइप करने के लिए टाइप से एक फ़ंक्शन पास कर सकता हूं। उदाहरण के लिए, मैं फ़ंक्शन (+1) या फ़ंक्शन reverse पास कर सकता हूं। आप कह रहे हैं कि "मुझे अब टाइप चुनना है" के बारे में सोच सकते हैं। (प्रकार चुनने के लिए तकनीकी शब्द तत्काल है ।)

    foo को कॉल करने पर प्रतिबंध अधिक कड़े हैं: foo लिए तर्क एक polymorphic फ़ंक्शन होना चाहिए। उस प्रकार के साथ, foo को पास करने वाले एकमात्र फ़ंक्शन id या फ़ंक्शन होते हैं जो हमेशा undefined तरह अलग हो जाते हैं या त्रुटियां हैं। कारण यह है कि foo साथ, तीर बायीं तरफ है, इसलिए foo के कॉलर को यह नहीं चुनना है कि यह क्या है- बल्कि यह foo का कार्यान्वयन है जो कि क्या है उसे चुनने के लिए। चूंकि bar में तीर के ऊपर तीर के बाईं ओर तीर बायीं तरफ है, तो कॉल साइट के बजाए फ़ंक्शन के शरीर में forall है।

सारांश: forall कीवर्ड की पूरी व्याख्या गणित की आवश्यकता होती है और केवल गणित का अध्ययन करने वाले किसी व्यक्ति द्वारा समझा जा सकता है। यहां तक ​​कि आंशिक स्पष्टीकरण गणित के बिना समझना मुश्किल है। लेकिन हो सकता है कि मेरी आंशिक, गैर-गणित स्पष्टीकरण थोड़ा सा मदद करें। रनस्ट पर runST और पेटन जोन्स runST !

अनुपूरक: शब्दकोष "ऊपर", "नीचे", "बाईं ओर"। इन्हें पाठ के तरीकों से लिखे जाने वाले कुछ भी नहीं हैं और सब कुछ अमूर्त-वाक्यविन्यास पेड़ों के साथ करना है। अमूर्त वाक्यविन्यास में, एक forall एक प्रकार चर का नाम लेता है, और उसके बाद एक पूर्ण प्रकार "नीचे" है। एक तीर दो प्रकार (तर्क और परिणाम प्रकार) लेता है और एक नया प्रकार (फ़ंक्शन प्रकार) बनाता है। तर्क प्रकार तीर के बाईं ओर "तीर है"; यह अमूर्त-वाक्यविन्यास पेड़ में तीर का बायां बच्चा है।

उदाहरण:

  • कुल forall a . [a] -> [a] forall a . [a] -> [a] , फोल तीर से ऊपर है; तीर के बाईं ओर क्या है [a]

  • में

    forall n f e x . (forall e x . n e x -> f -> Fact x f) 
                  -> Block n e x -> f -> Fact x f
    

    कोष्ठक में टाइप को "तीर के बाईं ओर एक फॉरल" कहा जाएगा। (मैं ऐसे अनुकूलक में इस तरह के प्रकार का उपयोग कर रहा हूं जिस पर मैं काम कर रहा हूं।)


अस्तित्वहीन अस्तित्व कैसे है?

मौजूदा-मात्रा के साथ, data परिभाषाओं में कुल forall इसका मतलब है कि, निहित मान किसी भी उपयुक्त प्रकार का हो सकता है, न कि यह सभी उपयुक्त प्रकारों का होना चाहिए। - याचिरु का जवाब

data परिभाषाओं में क्यों forall इसका एक स्पष्टीकरण isomorphic है (exists a. a) (छद्म-हास्केल) विकीबुक्स के "हास्केल / मौजूदा रूप से मात्राबद्ध प्रकार" में पाया जा सकता है।

निम्नलिखित एक संक्षिप्त शब्दशः सारांश है:

data T = forall a. MkT a -- an existential datatype
MkT :: forall a. a -> T -- the type of the existential constructor

जब पैटर्न-मिलान / MkT x , MkT x का प्रकार क्या है?

foo (MkT x) = ... -- -- what is the type of x?

x किसी भी प्रकार का हो सकता है (जैसा कि कुल forall बताया गया है), और इसलिए यह प्रकार है:

x :: exists a. a -- (pseudo-Haskell)

इसलिए, निम्नलिखित isomorphic हैं:

data T = forall a. MkT a -- an existential datatype
data T = MkT (exists a. a) -- (pseudo-Haskell)

कुल मिलाकर मतलब है

इन सब की मेरी सरल व्याख्या यह है कि "सभी के लिए वास्तव में मतलब है"। बनाने के लिए एक महत्वपूर्ण भेद परिभाषा बनाम फ़ंक्शन एप्लिकेशन पर forall का प्रभाव है।

एक forall मतलब है कि मूल्य या फ़ंक्शन की परिभाषा forall होनी चाहिए।

यदि परिभाषित की जाने वाली चीज एक बहुरूप मूल्य है , तो इसका मतलब है कि मान सभी उपयुक्त a लिए मान्य होना चाहिए, जो काफी प्रतिबंधित है।

यदि परिभाषित किया जा रहा है कि एक पॉलीमोर्फिक फ़ंक्शन है , तो इसका अर्थ यह है कि फ़ंक्शन सभी उपयुक्त a लिए मान्य होना चाहिए, जो कि प्रतिबंधक नहीं है क्योंकि सिर्फ इसलिए कि पॉलिमोर्फिक है, इसका मतलब यह नहीं है कि लागू होने वाले पैरामीटर को पॉलिमॉर्फिक होना चाहिए। यही है, अगर फ़ंक्शन सभी के लिए मान्य a , तो इसके विपरीत किसी भी उपयुक्त को फ़ंक्शन पर लागू किया जा सकता है । हालांकि, पैरामीटर के प्रकार को फ़ंक्शन परिभाषा में केवल एक बार चुना जा सकता है।

यदि forall पैरामीटर पैरामीटर के प्रकार (यानी, एक Rank2Type ) के अंदर है तो इसका मतलब है कि लागू पैरामीटर वास्तव में पॉलीमोर्फिक होना चाहिए, जो कि अंतिम अर्थ के विचार के अनुरूप होना चाहिए परिभाषा forall है। इस मामले में, पैरामीटर के प्रकार को फ़ंक्शन परिभाषा में एक से अधिक बार चुना जा सकता है ( "और फ़ंक्शन के कार्यान्वयन द्वारा चुना जाता है", जैसा कि नॉर्मन द्वारा इंगित किया गया है )

इसलिए, अस्तित्व में data परिभाषाओं का कारण किसी भी कारण की अनुमति देता है क्योंकि डेटा कन्स्ट्रक्टर एक पॉलिमॉर्फिक फ़ंक्शन है :

MkT :: forall a. a -> T

एमकेटी की तरह :: a -> *

जिसका मतलब है कि किसी भी समारोह में लागू किया जा सकता है। एक बहुलक मूल्य के विपरीत, कहते हैं:

valueT :: forall a. [a]

प्रकार का मूल्य :: a

जिसका अर्थ है कि वैल्यूटी की परिभाषा पॉलिमॉर्फिक होनी चाहिए। इस मामले में, valueT को सभी प्रकार की खाली सूची [] के रूप में परिभाषित किया जा सकता है।

[] :: [t]

मतभेद

भले ही इसका अर्थ forallसुसंगत है ExistentialQuantificationऔर RankNTypeअस्तित्व में अंतर है क्योंकि dataकन्स्ट्रक्टर पैटर्न पैटर्न में उपयोग किया जा सकता है। Ghc उपयोगकर्ता मार्गदर्शिका में दस्तावेज के रूप में :

जब पैटर्न मिलान होता है, तो प्रत्येक पैटर्न मिलान प्रत्येक अस्तित्व प्रकार प्रकार के लिए एक नया, विशिष्ट, प्रकार प्रस्तुत करता है। इन प्रकारों को किसी अन्य प्रकार से एकीकृत नहीं किया जा सकता है, न ही वे पैटर्न मिलान के दायरे से बच सकते हैं।


इस कीवर्ड के विभिन्न उपयोगों का कारण यह है कि यह वास्तव में कम से कम दो अलग-अलग प्रकार के सिस्टम एक्सटेंशन में उपयोग किया जाता है: उच्च-रैंक प्रकार, और अस्तित्व।

यह संभवतः उन दो चीजों को अलग-अलग पढ़ने और समझने के लिए सबसे अच्छा है, क्योंकि 'फोल' एक ही समय में दोनों में सिंटैक्स का उचित बिट क्यों है, इसकी व्याख्या करने की कोशिश करने के बजाय।


मेरा मूल जवाब:

क्या कोई स्पष्ट, सादे अंग्रेजी में संपूर्ण कीवर्ड को पूरी तरह से समझा सकता है

जैसा कि नॉर्मन इंगित करता है, प्रकार सिद्धांत से तकनीकी शब्द की एक स्पष्ट, सादा अंग्रेजी व्याख्या देना बहुत मुश्किल है। हम सब कोशिश कर रहे हैं हालांकि।

'फोरल' के बारे में याद रखने के लिए केवल एक चीज है: यह प्रकार को कुछ गुंजाइश से जोड़ती है । एक बार जब आप इसे समझ लेंगे, तो सबकुछ काफी आसान है। यह प्रकार के स्तर पर 'लैम्ब्डा' (या 'चलो' का एक रूप) के बराबर है - नॉर्मन रैमसे अपने उत्कृष्ट उत्तर में दायरे की इसी अवधारणा को व्यक्त करने के लिए "बाएं" / "उपरोक्त" की धारणा का उपयोग करता है।

'फोरल' के अधिकांश उपयोग बहुत ही सरल हैं, और आप उन्हें जीएचसी उपयोगकर्ता मैनुअल, एस 7.8 में पेश कर सकते हैं, विशेष रूप से उत्कृष्ट '7 'के नेस्टेड रूपों पर उत्कृष्ट एस 7.8.5।

हास्केल में, हम आमतौर पर प्रकार के लिए बाइंडर छोड़ देते हैं, जब प्रकार सार्वभौमिक रूप से quanitified है, जैसे:

length :: forall a. [a] -> Int

के बराबर है:

length :: [a] -> Int

बस।

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

टाइप सिस्टम को गहराई से समझने के लिए, आपको कुछ शब्दकोष सीखना होगा। यह कंप्यूटर विज्ञान की प्रकृति है। हालांकि, उपरोक्त की तरह सरल उपयोग, मान स्तर पर 'चलो' के समानता के माध्यम से सहजता से समझने में सक्षम होना चाहिए। लॉन्चबरी और पेटन जोन्स का एक महान परिचय है।


यहां स्पष्ट शब्दों में एक त्वरित और गंदे स्पष्टीकरण दिया गया है कि आप पहले ही परिचित होने की संभावना रखते हैं।

forall कीवर्ड वास्तव में केवल हास्केल में एक ही तरीके से उपयोग किया जाता है। जब आप इसे देखते हैं तो यह हमेशा एक ही चीज़ का मतलब है।

सार्वभौमिक मात्रा

एक सार्वभौमिक रूप से forall a. fa प्रकार एक प्रकार का फॉर्म forall a. fa forall a. fa उस प्रकार के एक मूल्य को एक ऐसे फ़ंक्शन के रूप में सोचा जा सकता है जो एक प्रकार को इसके तर्क के रूप में लेता है और प्रकार का मान देता है। सिवाय इसके कि हास्केल में इन प्रकार के तर्क टाइप सिस्टम द्वारा निहित रूप से पारित किए जाते हैं। इस "फ़ंक्शन" को आपको वही मान देना होगा, इससे कोई फर्क नहीं पड़ता कि यह किस प्रकार प्राप्त करता है, इसलिए मान polymorphic है

उदाहरण के लिए, टाइप forall a. [a] के लिए विचार करें forall a. [a] forall a. [a] । उस प्रकार का मान a और प्रकार लेता है और आपको उसी प्रकार के तत्वों की सूची देता a । बेशक, केवल एक ही संभावित कार्यान्वयन है। इसे आपको खाली सूची देना होगा क्योंकि a भी बिल्कुल प्रकार का हो सकता है। खाली सूची एकमात्र सूची मान है जो इसके तत्व प्रकार में बहुलक है (क्योंकि इसमें कोई तत्व नहीं है)।

या प्रकार के लिए forall a. a -> a forall a. a -> a । इस तरह के एक समारोह के कॉलर एक प्रकार a और एक प्रकार के मूल्य प्रदान करता a । कार्यान्वयन को तब उसी प्रकार के मूल्य को वापस a । फिर से केवल एक संभव कार्यान्वयन है। इसे उसी मूल्य को वापस करना होगा जो इसे दिया गया था।

मौजूदा मात्रा

एक अस्तित्व में मात्राबद्ध प्रकार के रूप में फॉर्म exists a. fa होगा exists a. fa exists a. fa , अगर हास्केल ने उस नोटेशन का समर्थन किया। उस प्रकार का एक मूल्य एक जोड़ी (या एक "उत्पाद") के रूप में सोचा जा सकता है जिसमें एक प्रकार का होता a और प्रकार fa का मूल्य होता है।

उदाहरण के लिए, यदि आपके पास प्रकार का मान exists a. [a] exists a. [a] , आपके पास कुछ प्रकार के तत्वों की एक सूची है। यह किसी भी प्रकार का हो सकता है, लेकिन अगर आपको नहीं पता कि यह क्या है तो आप ऐसी सूची में बहुत कुछ कर सकते हैं। आप इसे उलट सकते हैं, या आप तत्वों की संख्या गिन सकते हैं, या किसी अन्य सूची ऑपरेशन को निष्पादित कर सकते हैं जो तत्वों के प्रकार पर निर्भर नहीं है।

ठीक है, तो एक मिनट प्रतीक्षा करें। हास्केल निम्नलिखित "जैसे" अस्तित्वहीन "प्रकार को इंगित करने के लिए क्यों उपयोग करता है?

data ShowBox = forall s. Show s => SB s

यह भ्रमित हो सकता है, लेकिन यह वास्तव में डेटा कन्स्ट्रक्टर SB के प्रकार का वर्णन कर रहा है:

SB :: forall s. Show s => s -> ShowBox

एक बार निर्माण करने के बाद, आप ShowBox के प्रकार के मूल्य के बारे में सोच सकते हैं जिसमें दो चीजें शामिल हैं। यह प्रकार के मूल्य के साथ एक प्रकार का है। दूसरे शब्दों में, यह अस्तित्व में प्रमाणित प्रकार का मूल्य है। ShowBox वास्तव में exists s. Show s => s रूप में लिखा जा सकता है exists s. Show s => s यदि Haskell ने उस नोटेशन का समर्थन किया है तो exists s. Show s => s

runST और दोस्तों

यह देखते हुए, ये अलग कैसे हैं?

foo :: (forall a. a -> a) -> (Char,Bool)
bar :: forall a. ((a -> a) -> (Char, Bool))

आइए पहले bar । यह एक प्रकार का a और एक प्रकार का कार्य करता a -> a , और प्रकार का मूल्य (Char, Bool) उत्पन्न करता है। हम Int को a रूप में चुन सकते हैं और इसे उदाहरण के लिए Int -> Int प्रकार का कार्य दे सकते हैं। लेकिन foo अलग है। यह आवश्यक है कि foo का कार्यान्वयन किसी भी प्रकार को पारित करने में सक्षम हो, जिसे हम इसे देना चाहते हैं। तो एकमात्र कार्य जिसे हम उचित रूप से दे सकते हैं वह id

अब हम runST के प्रकार के अर्थ से निपटने में सक्षम होना चाहिए:

runST :: forall a. (forall s. ST s a) -> a

तो runST को टाइप के मूल्य का उत्पादन करने में सक्षम होना चाहिए, इससे कोई फर्क नहीं पड़ता कि हम किस प्रकार के रूप में देते हैं। ऐसा करने के लिए, इसे किसी प्रकार के तर्क की आवश्यकता है forall s. ST sa forall s. ST sa जो हुड के नीचे सिर्फ एक प्रकार का forall s. s -> (a, s) forall s. s -> (a, s) । तब उस कार्य को प्रकार (a, s) मूल्य का उत्पादन करने में सक्षम होना चाहिए (a, s) इससे कोई फर्क नहीं पड़ता कि runST के कार्यान्वयन के किस प्रकार का निर्णय लेना है।

ठीक है तो क्या हुआ? लाभ यह है कि यह runST के कॉलर पर बाधा डालता है जिसमें उस प्रकार का प्रकार शामिल नहीं हो सकता है। उदाहरण के लिए, आप इसे ST s [s] के प्रकार का मूल्य नहीं पारित कर सकते हैं। अभ्यास में इसका अर्थ यह है कि runST का कार्यान्वयन प्रकार के मूल्य के साथ उत्परिवर्तन करने के लिए स्वतंत्र है। प्रकार प्रणाली गारंटी देता है कि यह उत्परिवर्तन runST के कार्यान्वयन के लिए स्थानीय है।

runST का प्रकार रैंक -2 पॉलीमोर्फिक प्रकार का एक उदाहरण है क्योंकि इसके तर्क के प्रकार में एक forall क्वांटिफायर होता है। उपरोक्त foo का प्रकार रैंक 2 का भी है। एक सामान्य पॉलिमॉर्फिक प्रकार, जैसे कि bar की तरह, रैंक -1 है, लेकिन यह रैंक -2 बन जाता है यदि तर्क के प्रकारों को forall होने की आवश्यकता होती है, अपने स्वयं के forall क्वांटिफायर के साथ। और यदि कोई फ़ंक्शन रैंक -2 तर्क लेता है तो इसका प्रकार रैंक -3 है, और इसी तरह। आम तौर पर, एक प्रकार जो रैंक n पॉलिमॉर्फिक तर्क लेता है, रैंक n + 1







forall