हास्केल में किसी फ़ंक्शन - a (>) के बारे में क्या नियम हैं?


12

जैसा कि शीर्षक कहता है: हास्केल फ़ंक्शन रिटर्निंग यूनिट के मूल्यांकन की क्या गारंटी है? कोई सोचता है कि इस तरह के मामले में किसी भी तरह के मूल्यांकन को चलाने की कोई आवश्यकता नहीं है, कंपाइलर ऐसे सभी कॉल को तत्काल ()मूल्य के साथ बदल सकता है जब तक कि सख्ती के लिए स्पष्ट अनुरोध मौजूद नहीं हैं, इस मामले में कोड को यह तय करना होगा कि क्या होना चाहिए वापस ()या नीचे।
मैंने जीएचसीआई में इसके साथ प्रयोग किया है, और ऐसा लगता है कि इसके विपरीत होता है, अर्थात्, इस तरह के फ़ंक्शन का मूल्यांकन किया जाता है। एक बहुत ही आदिम उदाहरण होगा

f :: a -> ()
f _ = undefined

मूल्यांकन f 1की उपस्थिति के कारण एक त्रुटि फेंकता है undefined, इसलिए कुछ मूल्यांकन निश्चित रूप से होता है। यह स्पष्ट नहीं है कि मूल्यांकन कितना गहरा है, हालांकि; कभी-कभी यह उतना ही गहरा प्रतीत होता है जितना कि लौटने वाले कार्यों के लिए सभी कॉल का मूल्यांकन करना आवश्यक है ()। उदाहरण:

g :: [a] -> ()
g [] = ()
g (_:xs) = g xs

यदि यह कोड अनिश्चित काल के लिए प्रस्तुत किया जाता है g (let x = 1:x in x)। परन्तु फिर

f :: a -> ()
f _ = undefined
h :: a -> ()
h _ = ()

उस h (f 1)रिटर्न को दिखाने के लिए इस्तेमाल किया जा सकता है (), इसलिए इस मामले में सभी यूनिट-वैल्यू वाले सबएक्सप्रेस का मूल्यांकन नहीं किया जाता है। यहाँ सामान्य नियम क्या है?

ETA: बेशक मुझे आलस के बारे में पता है। मैं पूछ रहा हूँ कि संकलक लेखकों को इस विशेष मामले को आम तौर पर संभव से भी हल्का बनाने से रोकता है।

ईटीए 2: उदाहरणों का सारांश: जीएचसी ()बिल्कुल किसी अन्य प्रकार के रूप में व्यवहार करता है, जैसे कि एक सवाल था कि किस प्रकार के नियमित मूल्य के प्रकार को एक फ़ंक्शन से वापस किया जाना चाहिए। तथ्य यह है कि केवल एक ही ऐसा मूल्य है जो अनुकूलन एल्गोरिदम द्वारा उपयोग किया गया प्रतीत नहीं होता है (ab)।

ETA3: जब मैं हास्केल कहता हूं, तो मेरा मतलब है हास्केल-जैसा-परिभाषित-दर-रिपोर्ट, न कि हास्केल-ए-एच-इन-जीएचसी। लगता है कि एक धारणा के रूप में व्यापक रूप से साझा नहीं किया गया था जैसा कि मैंने कल्पना की थी (जो 'पाठकों के 100% द्वारा' था), या मैं शायद एक स्पष्ट प्रश्न तैयार कर सकता था। फिर भी, मुझे सवाल के शीर्षक को बदलने पर पछतावा है, क्योंकि यह मूल रूप से पूछा गया है कि इस तरह के एक समारोह के लिए क्या गारंटी है

ETA4: ऐसा लगेगा कि इस प्रश्न ने अपना पाठ्यक्रम चला दिया है, और मैं इसे अनुत्तरित मान रहा हूं। (मैं 'एक करीबी प्रश्न' समारोह की तलाश में था, लेकिन केवल 'अपने ही प्रश्न का उत्तर पाया' और जैसा कि इसका उत्तर नहीं दिया जा सकता है, मैं उस मार्ग से नीचे नहीं गया।) किसी ने भी रिपोर्ट में से कुछ भी नहीं लाया है जो इसे तय करेगा। , जो मुझे एक मजबूत, लेकिन निश्चित रूप से व्याख्या करने के लिए लुभाता है, लेकिन इस तरह के उत्तर के लिए भाषा की कोई गारंटी नहीं है। हम सभी जानते हैं कि वर्तमान जीएचसी कार्यान्वयन इस तरह के फ़ंक्शन का मूल्यांकन नहीं करेगा।

हास्केल के लिए एक OCaml ऐप पोर्ट करते समय मैंने वास्तविक समस्या में भाग लिया है। मूल ऐप में कई प्रकारों की पारस्परिक रूप से पुनरावर्ती संरचना थी, और कोड ने assert_structureN_is_correct1..6 या 7 में एन के लिए कई प्रकार के फ़ंक्शन की घोषणा की , जिनमें से प्रत्येक यूनिट वापस आ गई यदि संरचना वास्तव में सही थी और अपवाद नहीं थी, अगर यह नहीं थी । इसके अलावा, इन कार्यों ने एक-दूसरे को बुलाया क्योंकि उन्होंने शुद्धता की स्थिति को विघटित कर दिया। हास्केल में यह बेहतर तरीके से Either Stringसंन्यासी का उपयोग करता है , इसलिए मैंने इसे इस तरह से स्थानांतरित किया, लेकिन एक सैद्धांतिक मुद्दे के रूप में सवाल बना रहा। सभी इनपुट और उत्तर के लिए धन्यवाद।


1
यह काम में आलस्य है। जब तक किसी फ़ंक्शन के परिणाम की मांग नहीं की जाती है (उदाहरण के लिए एक कंस्ट्रक्टर के खिलाफ पैटर्न मिलान), फ़ंक्शन के शरीर का मूल्यांकन नहीं किया जाता है। अंतर देखने के लिए, तुलना करने का प्रयास करें h1::()->() ; h1 () = ()और h2::()->() ; h2 _ = ()। दोनों भागो h1 (f 1)और h2 (f 1), और देखते हैं कि केवल पहले एक की मांग (f 1)
ची '

1
"आलस्य यह तय करना होगा कि यह किसी भी तरह के मूल्यांकन के बिना () के साथ बदल जाता है।" इसका क्या मतलब है? सभी मामलों में f 1"प्रतिस्थापित" है undefined
oisdk 14

3
एक फ़ंक्शन ... -> ()1) समाप्त कर सकता है और वापस आ सकता है (), 2) एक अपवाद / रनटाइम त्रुटि के साथ समाप्त होता है और कुछ भी वापस करने में विफल रहता है, या 3) डायवर्ज (अनंत पुनरावर्तन)। जीएचसी केवल 1 मान लेने वाले कोड का अनुकूलन नहीं करता है) हो सकता है: यदि f 1मांग की जाती है, तो यह अपने मूल्यांकन को नहीं छोड़ता है और वापस लौटता है ()। हास्केल शब्दार्थ इसका मूल्यांकन करना है और देखना है कि 1,2,3 के बीच क्या होता है।
चि।

2
()इस प्रश्न में (या तो प्रकार या मूल्य) के बारे में वास्तव में कुछ खास नहीं है । यदि आप हर जगह () :: (), कहते हैं, सभी समान अवलोकन होते हैं 0 :: Int। ये सभी आलसी मूल्यांकन के पुराने उबाऊ परिणाम हैं।
डैनियल वैगनर

2
नहीं, "टालना" आदि हास्केल शब्दार्थ नहीं है। और प्रकार के दो संभावित मूल्य हैं (), ()और undefined
विल नेस 16

जवाबों:


10

आप इस धारणा से आते हैं कि प्रकार ()का केवल एक ही संभव मूल्य है,() और इस प्रकार यह अपेक्षा करते हैं कि किसी भी फ़ंक्शन कॉल प्रकार का मान लौटाते हुए ()स्वचालित रूप से मान का उत्पादन करने के लिए मान लिया जाए ()

यह हस्केल काम नहीं करता है। हर प्रकार के हास्केल में एक और मूल्य है, अर्थात् नहीं मूल्य, त्रुटि या तथाकथित "नीचे" नहीं है undefined। इस प्रकार एक मूल्यांकन वास्तव में हो रहा है:

main = print (f 1)

कोर भाषा के बराबर है

main = _Case (f 1) _Of x -> print x   -- pseudocode illustration

या (*)

main = _Case (f 1) _Of x -> putStr "()"

और कोर के _Caseहै के लिए मजबूर :

"ए का मूल्यांकन %case [अभिव्यक्ति] का मूल्यांकन करने से अभिव्यक्ति के मूल्यांकन का परीक्षण किया जाता है (" स्क्रूटिनी ")। स्क्रूटनी का मान %ofकीवर्ड के बाद वाले चर के लिए बाध्य होता है ..."।

मूल्य कमजोर सिर सामान्य रूप से मजबूर है। यह भाषा की परिभाषा का हिस्सा है।

हास्केल है नहीं एक कथात्मक प्रोग्रामिंग भाषा।


(*) print x = putStr (show x) और show () = "()", इसलिए showकॉल को पूरी तरह से संकलित किया जा सकता है।

मूल्य वास्तव में अग्रिम रूप में जाना जाता है (), और यहां तक ​​कि मूल्य के show ()रूप में अग्रिम में जाना जाता है "()"। फिर भी स्वीकार कर लिया हास्केल अर्थ विज्ञान की मांग है कि मूल्य (f 1), अग्रिम स्ट्रिंग में जाना जाता है कि मुद्रित करने के लिए आगे बढ़ने से पहले कमजोर सिर सामान्य रूप के लिए मजबूर किया जाता है "()"


संपादित करें: विचार करेंconcat (repeat []) । यह होना चाहिए [], या यह एक अनंत लूप होना चाहिए?

एक "घोषणात्मक भाषा" का उत्तर शायद सबसे अधिक है []। हास्केल का उत्तर है, अनंत लूप

आलस्य है "गरीब आदमी का कथात्मक प्रोग्रामिंग", लेकिन यह अभी भी नहीं है असली बात

edit2 : print $ h (f 1) == _Case (h (f 1)) _Of () -> print ()और केवल hमजबूर है, नहीं f; और इसके उत्तर का निर्माण hकरने के लिए इसकी परिभाषा के अनुसार कुछ भी मजबूर करने की आवश्यकता नहीं है h _ = ()

बिदाई टिप्पणी: आलस्य में डीएट्रे हो सकता है लेकिन इसकी परिभाषा नहीं है। आलस्य वह है जो यह है। इसे सभी मूल्यों के रूप में शुरू में परिभाषित किया गया है जो कि आने वाली मांगों के अनुसार WHNF के लिए मजबूर हैं main। यदि यह अपनी विशिष्ट परिस्थितियों के अनुसार एक निश्चित विशिष्ट मामले में नीचे से बचने में मदद करता है, तो यह करता है। यदि नहीं, तो नहीं। बस इतना ही।

यह अपनी पसंदीदा भाषा में, इसे महसूस करने के लिए इसे स्वयं लागू करने में मदद करता है। लेकिन हम सभी अंतरिम मूल्यों को ध्यान से बताकर किसी भी अभिव्यक्ति के मूल्यांकन का पता लगा सकते हैं क्योंकि वे अस्तित्व में आते हैं।


द्वारा जा रहे हैं रिपोर्ट , हमारे पास है

f :: a -> ()
f = \_ -> (undefined :: ())

फिर

print (f 1)
 = print ((\ _ ->  undefined :: ()) 1)
 = print          (undefined :: ())
 = putStrLn (show (undefined :: ()))

और साथ

instance Show () where
    show :: () -> String
    show x = case x of () -> "()"

यह जारी रहेगा

 = putStrLn (case (undefined :: ()) of () -> "()")

अब, धारा 3.17.3 रिपोर्ट के पैटर्न मिलान के औपचारिक शब्दार्थ कहते हैं

caseभावों के शब्दार्थ [दिए गए हैं] आंकड़े ३-३-३ में। किसी भी क्रियान्वयन को ऐसा व्यवहार करना चाहिए जिससे ये पहचान बनी रहे [...]।

और इस मामले (r)में चित्रा 3.2 राज्यों

(r)     case  of { K x1  xn -> e; _ -> e } =  
        where K is a data constructor of arity n 

() 0 का डेटा कंस्ट्रक्टर है, इसलिए यह वैसा ही है

(r)     case  of { () -> e; _ -> e } =  

और मूल्यांकन का समग्र परिणाम इस प्रकार है


2
मुझे आपका स्पष्टीकरण पसंद है। यह स्पष्ट और सरल है।
तीर

@DanielWagner मैं caseवास्तव में कोर से दिमाग में था, और अंतराल छेद की अनदेखी कर रहा था। :) मैंने कोर का उल्लेख करने के लिए संपादित किया है।
विल नेस

1
फोर्सिंग showद्वारा लागू नहीं किया जाएगा print? कुछ इस तरहshow x = case x of () -> "()"
user253751

1
मैं caseकोर में संदर्भित करता हूं , हास्केल में ही नहीं। हास्केल को कोर में अनुवादित किया गया है, जिसमें एक फोर्सिंग caseAFAIK है। आप सही हैं कि caseहास्केल अपने आप में मजबूर नहीं है। मैं स्कीम या एमएल में कुछ लिख सकता हूं (यदि मैं एमएल लिख सकता हूं), या स्यूडोकोड।
विल नेस

1
इस सबका आधिकारिक उत्तर शायद रिपोर्ट में कहीं है। मुझे पता है कि यहां कोई "अनुकूलन" नहीं चल रहा है, और "नियमित मूल्य" इस संदर्भ में एक सार्थक शब्द नहीं है। जो भी मजबूर है, मजबूर है। printप्रिंट करने के लिए जितनी आवश्यकता हो उतना बल। यह प्रकार को नहीं देखता है, प्रकार चला जाता है, मिटा दिया जाता है, जब तक कार्यक्रम चलता है, सही मुद्रण सबरूटीन पहले से ही चुना जाता है और संकलित समय पर, प्रकार के अनुसार संकलित किया जाता है; वह सबरूटीन अभी भी रन समय पर WHNF को अपने इनपुट मूल्य को लागू करने जा रहा है, और यदि यह अपरिभाषित था, तो यह एक त्रुटि का कारण होगा।
विल नेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.