Haskell Language
टाइप किए हुए छेद
खोज…
टिप्पणियों
हास्केल की ताकत में से एक है टाइप सिस्टम में अपने समस्या डोमेन के मॉडल भागों के लिए टाइप सिस्टम का लाभ उठाने की क्षमता। ऐसा करने में, व्यक्ति अक्सर बहुत जटिल प्रकारों का सामना करता है। जब इन प्रकारों के साथ कार्यक्रम लिखना (यानी इन प्रकारों के साथ मान) यह कभी-कभी सभी प्रकारों के 'टकराने' के लिए लगभग असहनीय हो जाता है। जीएचसी 7.8 के रूप में, एक नया सिंटैक्टिक फीचर है जिसे टाइप किया गया छेद कहा जाता है। टाइप किए गए छेद कोर भाषा के शब्दार्थ को नहीं बदलते हैं; वे विशुद्ध रूप से प्रोग्राम लिखने के लिए एक सहायता के रूप में हैं।
टाइप किए गए छेदों की गहराई से व्याख्या के लिए, साथ ही टाइप किए गए छेदों के डिजाइन की चर्चा के लिए, हास्केल विकी देखें ।
टाइप किए गए छेदों पर GHC उपयोगकर्ता गाइड की धारा।
टाइप किए गए छेदों का सिंटैक्स
एक टाइप किया गया छेद एक एकल अंडरस्कोर ( _
) या एक वैध हास्केल पहचानकर्ता है जो एक अभिव्यक्ति के संदर्भ में, गुंजाइश में नहीं है। टाइप किए गए छेदों के अस्तित्व से पहले, ये दोनों चीजें एक त्रुटि को ट्रिगर करती हैं, इसलिए नया सिंटैक्स किसी भी पुराने सिंटैक्स के साथ हस्तक्षेप नहीं करता है।
टाइप किए गए छिद्रों के व्यवहार को नियंत्रित करना
टाइप किए गए छेद का डिफ़ॉल्ट व्यवहार टाइप किए गए छेद का सामना करते समय एक संकलन-समय त्रुटि उत्पन्न करना है। हालांकि, उनके व्यवहार को ठीक करने के लिए कई झंडे हैं। ये झंडे निम्नानुसार संक्षेपित किए गए हैं ( GHC trac ):
डिफ़ॉल्ट रूप से जीएचसी ने टाइप किए गए छेदों को सक्षम किया है और एक संकलित त्रुटि पैदा करता है जब यह टाइप किए गए छेद का सामना करता है।
जब
-fdefer-type-errors
या-fdefer-typed-holes
सक्षम किया जाता है, तो छेद त्रुटियों को चेतावनी में बदल दिया जाता है और मूल्यांकन करने पर रनटाइम त्रुटियों में परिणाम होता है।डिफ़ॉल्ट रूप से चेतावनी ध्वज
-fwarn-typed-holes
है। बिना-fdefer-type-errors
या-fdefer-typed-holes
इस फ्लैग एक नो-ऑप है, क्योंकि टाइप किए गए छेद इन परिस्थितियों में एक एरर हैं। यदि दोनों में से कोई भी-fno-warn-typed-holes
ध्वज सक्षम होता है (टाइप किए गए छेद त्रुटियों को चेतावनियों में परिवर्तित करना)-fno-warn-typed-holes
ध्वज चेतावनी को निष्क्रिय करता है। इसका मतलब है कि संकलन चुपचाप सफल होता है और एक छेद का मूल्यांकन एक रनटाइम त्रुटि पैदा करेगा।
टाइप किए गए छेदों का शब्दार्थ
एक प्रकार के छेद का मूल्य केवल undefined
कहा जा सकता है, हालांकि एक टाइप किया हुआ छेद एक संकलन-समय त्रुटि को ट्रिगर करता है, इसलिए इसे मान निर्दिष्ट करने के लिए कड़ाई से आवश्यक नहीं है। हालाँकि, एक टाइप किया हुआ छेद (जब वे सक्षम होते हैं) एक संकलित समय त्रुटि (या आस्थगित प्रकार की त्रुटियों के साथ चेतावनी) पैदा करता है जो टाइप किए गए छेद का नाम बताता है, इसका सबसे सामान्य प्रकार, और किसी भी स्थानीय बाइंडिंग के प्रकार। उदाहरण के लिए:
Prelude> \x -> _var + length (drop 1 x)
<interactive>:19:7: Warning:
Found hole `_var' with type: Int
Relevant bindings include
x :: [a] (bound at <interactive>:19:2)
it :: [a] -> Int (bound at <interactive>:19:1)
In the first argument of `(+)', namely `_var'
In the expression: _var + length (drop 1 x)
In the expression: \ x -> _var + length (drop 1 x)
ध्यान दें कि GHCi उत्तर में दर्ज किए गए अभिव्यक्तियों में टाइप किए गए छेद के मामले में (जैसा कि ऊपर), दर्ज की गई अभिव्यक्ति का प्रकार भी रिपोर्ट किया गया है, क्योंकि it
(प्रकार [a] -> Int
)।
एक वर्ग उदाहरण को परिभाषित करने के लिए टाइप किए गए छेद का उपयोग करना
टाइप किए गए छेद एक इंटरैक्टिव प्रक्रिया के माध्यम से कार्यों को परिभाषित करना आसान बना सकते हैं।
मान लें कि आप एक वर्ग उदाहरण Foo Bar
(आपके कस्टम Bar
प्रकार के लिए, इसे कुछ पॉलीमॉर्फिक लाइब्रेरी फ़ंक्शन के साथ उपयोग करने के लिए परिभाषित करना चाहते हैं जो Foo
उदाहरण की आवश्यकता है)। अब आप परंपरागत रूप से Foo
के दस्तावेज़ीकरण को देखेंगे, यह पता Foo
कि आपको किन तरीकों को परिभाषित करने की ज़रूरत है, उनके प्रकारों की जांच करें आदि - लेकिन टाइप किए गए छेदों के साथ, आप वास्तव में इसे छोड़ सकते हैं!
सबसे पहले बस एक डमी उदाहरण को परिभाषित करें:
instance Foo Bar where
कंपाइलर अब शिकायत करेंगे
Bar.hs:13:10: Warning:
No explicit implementation for
‘foom’ and ‘quun’
In the instance declaration for ‘Foo Bar’
ठीक है, इसलिए हमें Bar
लिए foom
को परिभाषित करने की आवश्यकता है। लेकिन क्या है कि माना जाता है? फिर हम प्रलेखन में देखने के लिए बहुत आलसी हैं, और बस कंपाइलर से पूछें:
instance Foo Bar where
foom = _
यहाँ हमने टाइप किया हुआ छेद एक साधारण "प्रलेखन क्वेरी" के रूप में उपयोग किया है। संकलक आउटपुट
Bar.hs:14:10:
Found hole ‘_’ with type: Bar -> Gronk Bar
Relevant bindings include
foom :: Bar -> Gronk Bar (bound at Foo.hs:4:28)
In the expression: _
In an equation for ‘foom’: foom = _
In the instance declaration for ‘Foo Bar’
ध्यान दें कि कंपाइलर ने किस प्रकार के ठोस प्रकार Bar
साथ वर्ग प्रकार चर पहले ही भर दिया है जिसे हम इसके लिए तुरंत करना चाहते हैं। यह कक्षा के प्रलेखन में पाए जाने वाले बहुरूपता की तुलना में हस्ताक्षर को समझने में बहुत आसान बना सकता है, खासकर यदि आप एक बहु-पैरामीटर प्रकार वर्ग जैसे अधिक जटिल विधि के साथ काम कर रहे हैं।
लेकिन Gronk
क्या नरक है? इस बिंदु पर, हेओयू से पूछना शायद एक अच्छा विचार है। हालाँकि, हम इसके बिना भी दूर हो सकते हैं: एक अंधे अनुमान के रूप में, हम मानते हैं कि यह न केवल एक प्रकार का निर्माता है, बल्कि एकल मूल्य निर्माता भी है, अर्थात यह एक फ़ंक्शन के रूप में इस्तेमाल किया जा सकता है जो किसी भी तरह से एक Gronk a
मान का उत्पादन करेगा। इसलिए हम कोशिश करते हैं
instance Foo Bar where
foom bar = _ Gronk
यदि हम भाग्यशाली हैं, तो Gronk
वास्तव में एक मूल्य है, और संकलक अब कहेगा
Found hole ‘_’
with type: (Int -> [(Int, b0)] -> Gronk b0) -> Gronk Bar
Where: ‘b0’ is an ambiguous type variable
ठीक है, यह बदसूरत है - पहली बार में ध्यान दें कि Gronk
पास दो तर्क हैं, इसलिए हम अपने प्रयास को परिष्कृत कर सकते हैं:
instance Foo Bar where
foom bar = Gronk _ _
और यह अब बहुत स्पष्ट है:
Found hole ‘_’ with type: [(Int, Bar)]
Relevant bindings include
bar :: Bar (bound at Bar.hs:14:29)
foom :: Bar -> Gronk Bar (bound at Foo.hs:15:24)
In the second argument of ‘Gronk’, namely ‘_’
In the expression: Gronk _ _
In an equation for ‘foom’: foom bar = Gronk _ _
अब आप bar
वैल्यू को डिकंस्ट्रक्ट करके आगे की प्रगति कर सकते हैं (घटक तब दिखाई देंगे, प्रकार के साथ, Relevant bindings
सेक्शन में)। अक्सर, यह कुछ बिंदु पर पूरी तरह से स्पष्ट है कि सही परिभाषा क्या होगी, क्योंकि आप सभी उपलब्ध तर्क देखते हैं और प्रकार एक पहेली की तरह एक साथ फिट होते हैं। या वैकल्पिक रूप से, आप देख सकते हैं कि परिभाषा असंभव है और क्यों।
यह सब इंटरैक्टिव संकलन के साथ एक संपादक में सबसे अच्छा काम करता है, उदाहरण के लिए Emacs haskell-mode के साथ। फिर आप एक व्याख्यात्मक गतिशील अनिवार्य भाषा के लिए IDE में माउस-ओवर वैल्यू प्रश्नों की तरह टाइप किए गए छेद का उपयोग कर सकते हैं, लेकिन सभी सीमाओं के बिना।