यह इस प्रकार है कि किस प्रकार के चर मानक हैं और मानक हास्केल में मात्राबद्ध हैं। तुम इतनी तरह दूसरे संस्करण काम कर सकते हैं:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module RigidProblem where
data Wrapped a = Wrapped a
alpha :: forall s. IO s -> IO()
alpha x = do
rv <- wrapit
return()
where
wrapit :: IO (Wrapped s)
wrapit = do
a <- x
return (Wrapped a)
दो परिवर्तन किए गए हैं: RankNTypes और ScopedTypeVariables भाषा एक्सटेंशन सक्षम रहे हैं और स्पष्ट forall s
alpha
के प्रकार के हस्ताक्षर में जोड़ा जाता है। दो एक्सटेंशन में से पहला यह है कि हमें स्पष्ट forall s
को alpha
के शरीर के दायरे में दायरे में लाने की अनुमति देता है, जबकि दूसरा यह बनाता है कि wrapit
पर हस्ताक्षर प्रकार अनुमान इंजन से अंतर्निहित नहीं है forall s
- इसके बजाय, उस हस्ताक्षर में s
को एक प्रकार परिवर्तनीय नाम दिया जाता है जो दायरे में होना चाहिए और इसके साथ पहचाना जाना चाहिए।
हास्केल में वर्तमान डिफ़ॉल्ट स्थिति, अगर मैं सही ढंग से समझ, बस इतना ही कठोर प्रकार चर (जिसका अर्थ है प्रकार हस्ताक्षर स्पष्ट रूप से प्रोग्रामर द्वारा प्रदान में होने वाली प्रकार चर) परोक्ष मात्रा निर्धारित कर रहे हैं और lexically scoped नहीं है, ताकि वहाँ है एक आंतरिक दायरे में दिए गए एक स्पष्ट हस्ताक्षर में एक बाहरी दायरे से एक कठोर प्रकार चर को संदर्भित करने का कोई तरीका नहीं है ... (ओह परेशान है, मुझे यकीन है कि कोई इसे इससे बेहतर वाक्यांश दे सकता है।) वैसे भी, प्रकार के चेकर के बिंदु से देखें, s
alpha
के हस्ताक्षर में और wrapit
के हस्ताक्षर में से एक पूरी तरह से असंबंधित है और इसे एकीकृत नहीं किया जा सकता है - इस प्रकार त्रुटि।
जीएचसी दस्तावेज़ों से और अधिक जानकारी के लिए हास्केल प्राइम विकी से this page देखें।
अद्यतन: मुझे अभी एहसास हुआ कि मैंने कभी समझाया नहीं कि पहला संस्करण क्यों काम करता है। पूर्णता के लिए: ध्यान दें कि पहले संस्करण के साथ, आप s
के स्थान पर wrapit
के हस्ताक्षर में t
का उपयोग कर सकते हैं और कुछ भी नहीं बदलेगा। आप where
ब्लॉक से wrapit
भी ले सकते हैं और इसे एक अलग शीर्ष स्तर का फ़ंक्शन बना सकते हैं। मुख्य बिंदु यह है कि यह एक बहुलक कार्य है, ताकि wrapit x
का प्रकार x
के प्रकार से निर्धारित किया गया हो। alpha
के हस्ताक्षर में उपयोग किए गए पहले संस्करण wrapit
के हस्ताक्षर में उपयोग किए जाने वाले प्रकार परिवर्तक का कोई संबंध यहां किसी भी उपयोग का नहीं होगा। दूसरे संस्करण के साथ यह निश्चित रूप से अलग है और आपको wrapit
के s
को alpha
के s
जैसी ही चीज़ बनने के लिए उपरोक्त उल्लिखित चाल का सहारा लेना होगा।
स्रोत
2010-02-18 07:38:18
यह उत्तर बिल्कुल सही है, लेकिन मैं केवल जोर के लिए मुख्य बिंदु निकालना चाहता हूं: एक प्रकार के हस्ताक्षर में चर के पास उस हस्ताक्षर पर विस्तार होता है, न कि संबंधित परिभाषा के पूरे शरीर को। तो आपके उदाहरणों में से दो में से कोई भी असंबंधित नहीं है। 'ScopedTypeVariables' एक्सटेंशन 'नियम' के साथ स्पष्ट रूप से प्रमाणित चर के लिए इस नियम को संशोधित करता है। –