हास्केल घोषणा में विस्मयादिबोधक चिह्न का क्या अर्थ है?


261

मैं निम्नलिखित परिभाषा के पार आया क्योंकि मैंने इसे चलाने के लिए एक वास्तविक परियोजना का उपयोग करके हास्केल सीखने की कोशिश की। मुझे समझ में नहीं आता कि प्रत्येक तर्क के सामने विस्मयादिबोधक चिह्न क्या है और मेरी पुस्तकों ने इसका उल्लेख नहीं किया।

data MidiMessage = MidiMessage !Int !MidiMessage

13
मुझे संदेह है कि यह एक बहुत ही सामान्य प्रश्न हो सकता है; मैं स्पष्ट रूप से खुद को ठीक उसी चीज के बारे में सोचकर याद करता हूं, जब वापस आता है।
15:15 बजे cjs

जवाबों:


313

यह एक सख्त घोषणा है। मूल रूप से, इसका अर्थ है कि जब डेटा संरचना मान बनाया जाता है, तो इसका मूल्यांकन "कमजोर सिर सामान्य रूप" के रूप में किया जाना चाहिए। आइए एक उदाहरण देखें, ताकि हम यह देख सकें कि इसका क्या अर्थ है:

data Foo = Foo Int Int !Int !(Maybe Int)

f = Foo (2+2) (3+3) (4+4) (Just (5+5))

fउपरोक्त फ़ंक्शन , जब मूल्यांकन किया जाता है, तो एक "थंक" लौटाएगा: अर्थात, इसके मूल्य का पता लगाने के लिए कोड। उस बिंदु पर, एक फू भी अभी तक मौजूद नहीं है, बस कोड।

लेकिन किसी बिंदु पर कोई इसके अंदर देखने की कोशिश कर सकता है, शायद एक पैटर्न मैच के माध्यम से:

case f of
     Foo 0 _ _ _ -> "first arg is zero"
     _           -> "first arge is something else"

यह वह करने के लिए पर्याप्त कोड निष्पादित करने जा रहा है जिसे इसकी आवश्यकता है, और अधिक नहीं। तो यह चार मानकों के साथ एक फू पैदा करेगा (क्योंकि आप इसके बिना इसे अंदर नहीं देख सकते हैं)। पहला, चूंकि हम इसका परीक्षण कर रहे हैं, हमें सभी तरह से मूल्यांकन करने की आवश्यकता है 4, जहां हमें एहसास होता है कि यह मेल नहीं खाता है।

दूसरे का मूल्यांकन करने की आवश्यकता नहीं है, क्योंकि हम इसका परीक्षण नहीं कर रहे हैं। इस प्रकार, 6उस मेमोरी लोकेशन में स्टोर होने के बजाय , हम कोड को संभवतया मूल्यांकन के लिए स्टोर करेंगे (3+3)। अगर कोई इसे देखता है तो यह केवल 6 में बदल जाएगा।

तीसरा पैरामीटर, हालांकि, इसके !सामने एक है, इसलिए इसका कड़ाई से मूल्यांकन किया जाता है: (4+4)निष्पादित किया जाता है, और 8उस मेमोरी स्थान में संग्रहीत किया जाता है।

चौथे पैरामीटर का भी कड़ाई से मूल्यांकन किया जाता है। लेकिन यहाँ जहाँ यह थोड़ा मुश्किल हो जाता है: हम पूरी तरह से मूल्यांकन नहीं कर रहे हैं, लेकिन केवल कमजोर सामान्य रूप से। इसका मतलब यह है कि हम यह पता लगाते हैं कि यह कुछ है, Nothingया इसे Justस्टोर करें, लेकिन हम आगे नहीं बढ़ते हैं। इसका मतलब है कि हम स्टोर नहीं करते हैं, Just 10लेकिन वास्तव Just (5+5)में ठग को निर्विवाद रूप से छोड़ देते हैं। यह जानना महत्वपूर्ण है, हालांकि मुझे लगता है कि इसके सभी निहितार्थ इस प्रश्न के दायरे से परे हैं।

यदि आप BangPatternsभाषा एक्सटेंशन को सक्षम करते हैं , तो आप उसी तरह से फ़ंक्शन तर्कों को एनोटेट कर सकते हैं:

f x !y = x*y

f (1+1) (2+2)ठग वापस आ जाएगा (1+1)*4


16
यह बहुत मददगार है। मैं यह सोचने में मदद नहीं कर सकता कि क्या हास्केल शब्दावली लोगों को "कमजोर सामान्य सिर के रूप", "सख्त" और इसके बाद के शब्दों के साथ समझने के लिए और अधिक जटिल बना रही है। अगर मैं तुम्हें सही ढंग से समझूं, तो ऐसा लगता है! ऑपरेटर का तात्पर्य बाद में मूल्यांकन करने के लिए एक अनाम ब्लॉक को संग्रहीत करने के बजाय एक अभिव्यक्ति के मूल्यांकन किए गए मूल्य को संग्रहीत करना है। क्या यह एक उचित व्याख्या है या इसमें कुछ अधिक है?
डेविड

71
@ डेविड सवाल यह है कि मूल्य का मूल्यांकन करना कितना दूर है। कमजोर-सिर सामान्य रूप का अर्थ है: इसका मूल्यांकन तब तक करें जब तक कि आप सबसे बाहरी कंस्ट्रक्टर तक न पहुंच जाएं। सामान्य रूप का अर्थ है पूरे मूल्य का मूल्यांकन करें जब तक कि कोई भी अविकसित घटक शेष न हों। क्योंकि हास्केल सभी प्रकार के मूल्यांकन गहराई के लिए अनुमति देता है, इसका वर्णन करने के लिए एक समृद्ध शब्दावली है। आप इन भेदों को उन भाषाओं में नहीं पाते हैं जो केवल कॉल-बाय-वैल्यू शब्दार्थ का समर्थन करती हैं।
डॉन स्टीवर्ट

8
@ डेविड: मैंने यहां अधिक गहराई से स्पष्टीकरण लिखा: हास्केल: कमजोर हेड नॉर्मल फॉर्म क्या है? । हालांकि मैं धमाकेदार पैटर्न या कठोरता एनोटेशन का उल्लेख नहीं करता, वे उपयोग करने के बराबर हैं seq
हमार

1
सिर्फ यह सुनिश्चित करने के लिए कि मैं समझ गया: क्या यह आलस्य केवल एक अज्ञात समय के तर्कों पर निर्भर करता है? Ie यदि स्रोत कोड में वास्तव में एक कथन (2 + 2) है , तो क्या ज्ञात संख्याओं को जोड़ने के लिए कोड रखने के बजाय इसे अभी भी 4 के लिए अनुकूलित किया जाएगा ?
हाय-एंजेल

1
हाय-एंजेल, यह वास्तव में ऊपर तक है कि कंपाइलर ऑप्टिमाइज़ करना चाहता है। यद्यपि हम यह कहने के लिए बैंग्स का उपयोग करते हैं कि हम कुछ चीजों को सामान्य सिर के कमजोर होने के लिए मजबूर करना चाहते हैं, हमारे पास ऐसा करने के लिए कोई रास्ता नहीं है (और न ही हमें ज़रूरत है या नहीं) "कृपया सुनिश्चित करें कि आप अभी तक इस थन का मूल्यांकन नहीं करते हैं अगला कदम।" एक शब्दार्थ से, "n = 2 + 2" को देखते हुए, आप यह भी नहीं बता सकते हैं कि n के किसी विशेष संदर्भ का मूल्यांकन अभी किया जा रहा है या पहले मूल्यांकन किया गया था।
cjs

92

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

data Foo = Foo Int !Int

first (Foo x _) = x
second (Foo _ y) = y

चूंकि गैर-सख्त तर्क का मूल्यांकन नहीं किया जाता है second, इसलिए पास होने से undefinedसमस्या पैदा नहीं होती है:

> second (Foo undefined 1)
1

undefinedभले ही हम मूल्य का उपयोग न करें, लेकिन सख्त तर्क नहीं हो सकता है :

> first (Foo 1 undefined)
*** Exception: Prelude.undefined

2
कर्ट सैम्पसन के उत्तर की तुलना में यह बेहतर है क्योंकि यह वास्तव में उपयोगकर्ता के अवलोकन योग्य प्रभावों की व्याख्या करता है जो !प्रतीक को लागू करने के बजाए लागू करने के विवरण में होता है।
डेविड ग्रेसन

26

मेरा मानना ​​है कि यह एक सख्ती की गई टिप्पणी है।

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

इस पृष्ठ पर अधिक जानकारी है: प्रदर्शन / सख्ती


हम्म, आपके द्वारा संदर्भित पृष्ठ का उदाहरण उपयोग के बारे में बात करता है! जब एक समारोह आह्वान। लेकिन यह एक प्रकार की घोषणा में डालने से अलग लगता है। मैं क्या खो रहा हूँ?
डेविड

एक प्रकार का एक उदाहरण बनाना भी एक अभिव्यक्ति है। आप दिए गए तर्कों के रूप में प्रकार के निर्माणकर्ताओं के बारे में सोच सकते हैं जो निर्दिष्ट प्रकार के नए उदाहरण लौटाते हैं।
क्रिस वेस्ट

4
वास्तव में, सभी इरादों और उद्देश्यों के लिए, टाइप करें कंस्ट्रक्टर्स हैं कार्यों; आप उन्हें आंशिक रूप से लागू कर सकते हैं, उन्हें अन्य कार्यों (जैसे, map Just [1,2,3][जस्ट १, जस्ट २, जस्ट ३]] और इतने पर पास कर सकते हैं। मुझे उनके साथ मेल खाने की क्षमता के साथ-साथ पूरी तरह से असंबंधित सुविधा के बारे में सोचना मददगार लगता है।
cjs
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.