2012-05-15 4 views
20

क्या यह संकलक को अनुकूलित करने में मदद करता है, या यह अतिरिक्त प्रकार के हस्ताक्षर जोड़ने के लिए बस अधिशेष काम करता है? उदाहरण के लिए, एक अक्सर देखता है:क्लॉज में टाइप हस्ताक्षर का उपयोग करना इतना असामान्य क्यों है?

foo :: a -> b 
foo x = bar x 
     where bar x = undefined 

के बजाय:

foo :: a -> b 
foo x = bar x 
     where bar :: a -> b 
      bar x = undefined 

अगर मैं शीर्ष स्तर प्रकार हस्ताक्षर छोड़ देते हैं, GHC मुझे एक चेतावनी देता है, तो अगर मैं चेतावनी नहीं मिलता है मैं काफी हूँ आत्मविश्वास मेरा कार्यक्रम सही है। लेकिन अगर मैं किसी खंड में हस्ताक्षर छोड़ देता हूं तो कोई चेतावनी जारी नहीं की जाती है।

+0

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

+7

इसके अलावा, इनमें से कई स्थानीय परिभाषाओं को बाहरी स्कोप से प्रकार चरों तक पहुंचने की आवश्यकता होती है, जो 'asTypeOf' और दोस्तों के साथ कोड को अव्यवस्थित करने की आवश्यकता होती है, जब तक कि आप' ScopedTypeVariables' का उपयोग न करें। – Vitus

+1

यदि आपका कार्य एक प्रकार की घोषणा पाने के लिए पर्याप्त महत्वपूर्ण है, तो इसे प्रथम श्रेणी का नागरिक क्यों न बनाएं? – rotskoff

उत्तर

17

अक्सर where खंडों में परिभाषाएं परिभाषित करने के लिए स्वयं को दोहराने से बचने के लिए हैं यदि उप-अभिव्यक्ति परिभाषा में एक से अधिक बार होती है। ऐसे मामले में, प्रोग्रामर इनलाइन उप-अभिव्यक्तियों को लिखने के लिए स्थानीय परिभाषा को सरल स्टैंड-इन के रूप में सोचता है। आप आम तौर पर इनलाइन उप-अभिव्यक्तियों को स्पष्ट रूप से टाइप नहीं करेंगे, इसलिए आप where परिभाषा को टाइप नहीं करते हैं। यदि आप इसे टाइपिंग पर सहेजने के लिए कर रहे हैं, तो प्रकार की घोषणा आपकी सभी बचत को मार देगी।

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

इंगो के जवाब जानबूझ एक स्थानीय परिभाषा करने के लिए एक प्रकार दे रही है नहीं के लिए एक अच्छा कारण देता है, लेकिन मुझे लगता है मुख्य कारण यह है कि कई प्रोग्रामर अंगूठे का नियम है कि प्रकार घोषणाओं शीर्ष स्तर परिभाषाएँ नहीं बल्कि के लिए प्रदान किया आत्मसात किया है स्थानीय परिभाषाओं के लिए जिस तरह से उन्होंने हास्केल सीखा।

0

एक प्रकार का हस्ताक्षर जोड़ना आपके कोड को तेज़ी से बना सकता है। उदाहरण के लिए ले लो निम्नलिखित कार्यक्रम (फाइबोनैचि):

result = fib 25 ; 
-- fib :: Int -> Int 
fib x = if x<2 then 1 else (fib (x-1)) + (fib (x-2)) 
  • 2 लाइन में एनोटेशन के बिना, यह 0.010 सेकंड लेता है। चलाने के लिए।
  • Int -> Int एनोटेशन के साथ, इसमें 0.002 सेकंड लगते हैं।

यह तब होता है अगर आप fib के बारे में कुछ भी कहना नहीं है, यह जिसका अर्थ है कि रनटाइम के दौरान, अतिरिक्त डेटा संरचनाओं ("शब्दकोशों") के कार्यों के बीच पारित किया जा करना होगा fib :: (Num a, Num a1, Ord a) => a -> a1 के रूप में लिखा जाता है, जा रहा है क्योंकि Num/Ord टाइपक्लास का प्रतिनिधित्व करें।

+1

सवाल स्थानीय परिभाषाओं के प्रकार हस्ताक्षर के बारे में पूछता है। शीर्ष स्तर की परिभाषाओं के लिए प्रकार हस्ताक्षर देने के लिए वास्तव में बहुत आम है। – Vitus

+2

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

11

अक्सर where घोषणाओं का उपयोग लघु, स्थानीय चीजों के लिए किया जाता है, जिनमें सरल प्रकार होते हैं, या प्रकार आसानी से अनुमानित होते हैं। नतीजतन, प्रकार जोड़ने के लिए मानव या कंपाइलर के लिए कोई लाभ नहीं है।

यदि प्रकार जटिल है, या अनुमानित नहीं किया जा सकता है, तो आप प्रकार जोड़ना चाहेंगे।

मोनोमोर्फिक प्रकार हस्ताक्षर देने से शीर्ष स्तर के कार्यों को तेज़ कर दिया जा सकता है, where खंडों में स्थानीय परिभाषाओं के लिए यह बहुत अधिक जीत नहीं है, क्योंकि जीएचसी किसी भी तरह से ज्यादातर मामलों में परिभाषाओं को रेखांकित और अनुकूलित करेगा।

20

स्थानीय कार्यों की एक श्रेणी मौजूद है जिसका प्रकार हास्केल में लिखा नहीं जा सकता है (फैंसी जीएचसी एक्सटेंशन का उपयोग किए बिना)। उदाहरण के लिए:

f :: a -> (a, Int) 
f h = g 1 
    where g n = (h, n) 

इसका कारण यह है, जबकि f प्रकार हस्ताक्षर में a बहुरूपी बाहर f से देखा जाता है, यह तो f के भीतर से है। g में, यह कुछ अज्ञात प्रकार है, लेकिन कोई प्रकार नहीं है, और (मानक) हास्केल अपनी प्रकार की भाषा में "उस फ़ंक्शन के पहले तर्क के समान प्रकार" को व्यक्त नहीं कर सकता है।

+4

हालांकि '{- # LANGUAGE ScopedTypeVariables # -} आपको' g :: int -> (a, int) 'प्रकार देने की अनुमति देता है, यदि आप' f' 'के लिए टाइप हस्ताक्षर को संशोधित करते हैं। ए -> (ए, इंट) '। –

संबंधित मुद्दे