हास्केल के "कुछ भी नहीं" फ़ंक्शन, आईडी, मेमोरी के टन का उपभोग क्यों करता है?


112

हास्केल में एक पहचान फ़ंक्शन होता है जो इनपुट को अपरिवर्तित लौटाता है। परिभाषा सरल है:

id :: a -> a
id x = x

तो मज़े के लिए, यह आउटपुट होना चाहिए 8:

f = id id id id id id id id id id id id id id id id id id id id id id id id id id id
main = print $ f 8

कुछ सेकंड (और टास्क मैनेजर के अनुसार लगभग 2 जीबी मेमोरी) के बाद, संकलन विफल हो जाता है ghc: out of memory। इसी तरह, दुभाषिया कहता है ghci: out of memory

चूंकि idयह एक बहुत ही सरल कार्य है, इसलिए मैं इसे चलाने के समय या संकलन समय में एक मेमोरी बोझ होने की उम्मीद नहीं करूंगा। सभी मेमोरी किसके लिए उपयोग की जा रही है?


11
आप उन idएस की रचना करना चाहते हैं । VIM में, की परिभाषा पर कर्सर के साथ f, यह करें :s/id id/id . id ./g:।
टोबियास ब्रांट

जवाबों:


135

हम के प्रकार को जानते हैं id,

id :: a -> a

और जब हम इसके लिए विशेषज्ञ होते हैं id id, तो बाईं ओर की प्रतिलिपि idटाइप होती है:

id :: (a -> a) -> (a -> a)

और फिर जब आप इस फिर से सबसे बाईं ओर के लिए विशेषज्ञ idमें id id id, आपको मिलता है:

id :: ((a -> a) -> (a -> a)) -> ((a -> a) -> (a -> a))

तो आप प्रत्येक को idजोड़कर देखते हैं, सबसे बाईं ओर idका हस्ताक्षर बड़ा है।

ध्यान दें कि संकलन के दौरान प्रकार हटा दिए जाते हैं, इसलिए यह केवल जीएचसी में मेमोरी को ले जाएगा। यह आपके प्रोग्राम में मेमोरी नहीं लेगा।


मुझे याद है कि ओकासाकी कुछ इसी तरह की परेशानी में चल रही थी जब उसने हास्केल में एक आरपीएन कैलकुलेटर लिखा था।
dfeuer

3
सवाल, शायद, यह है कि क्या जीएचसी को इस तरह की चीज़ को और अधिक सुंदर तरीके से संभालने का तरीका ढूंढना चाहिए। विशेष रूप से, प्रकार बहुत बड़ा है जब पूर्ण रूप से लिखा जाता है, लेकिन इसमें बहुत अधिक मात्रा में दोहराव है - क्या इस तरह की चीजों को संपीड़ित करने के लिए साझाकरण का उपयोग किया जा सकता है? क्या उन्हें संसाधित करने का एक कुशल तरीका है?
dfeuer

5
@dfeuer ghci में टाइप करने की कोशिश करें। आप प्रतिक्रिया की गति से देखेंगे कि यह उचित साझा करना चाहिए। मुझे संदेह है कि यह साझाकरण खो गया है - स्पष्ट कारणों के लिए - एक बार जब आप किसी अन्य मध्यवर्ती प्रतिनिधित्व (जैसे कोर) में अनुवाद करते हैं।
डैनियल वैगनर

4
इसका अर्थ है कि यदि idबार- nबार दोहराया जाता है, तो इसके प्रकार का स्थान आनुपातिक है 2^n। रेयान के कोड 2^27में टाइप किए गए प्रकार को टाइप का प्रतिनिधित्व करने के लिए आवश्यक अन्य संरचना के अलावा इसके प्रकार चर के संदर्भों की आवश्यकता होगी , जो कि शायद सबसे बड़ा है जिससे आप सबसे अधिक प्रकार की अपेक्षा करते हैं।
डेविड

58
भोलेपन के साथ टाइपिंग का अनुमान दोगुना घातीय है, बड़ी चतुराई से इस प्रकार के भावों में साझा करके आप इसे केवल घातांक तक ला सकते हैं। लेकिन इससे कोई फर्क नहीं पड़ता कि आप क्या करते हैं, कुछ सरल भाव होंगे जो टाइप चेकर को विस्फोट कर देंगे। सौभाग्य से, ये व्यावहारिक प्रोग्रामिंग में नहीं होते हैं।
अगस्त
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.