एक्सेसिंग सिस्टम क्यों है। Info Haskell में IO ऑपरेशन नहीं माना जाता है?


25

मॉड्यूल में System.Infoमैं इन कार्यों को देखता हूं:

os :: String
arch :: String
compilerName :: String
compilerVersion :: Version

वहां क्यों नहीं IOहै? वे सिस्टम तक पहुंच रहे हैं ... क्या मैं गलत हूं? मेरी उम्मीद कुछ इस तरह थी:

os :: IO String
arch :: IO String
compilerName :: IO String
compilerVersion :: IO Version

उदाहरण:

      print os            -- "darwin"
      print arch          -- "x86_64"
      print compilerName  -- "ghc"

जवाबों:


29

आपको वह जानकारी रनटाइम पर नहीं मिल रही है । वे संकलक में हार्डकोडेड हैं जैसा कि आपके सिस्टम पर स्थापित है।

यदि आप http://hackage.haskell.org/package/base-4.12.0.0/docs/src/System.Info.htmlcompilerName में पाए गए परिभाषा को देखें तो यह सबसे स्पष्ट है ।

compilerName :: String
compilerName = "ghc"

लेकिन यहां तक ​​कि जैसे कुछ os

os :: String
os = HOST_OS

एक अन्यथा अपरिभाषित नाम HOST_OS(एक बड़े अक्षर के साथ शुरू होने वाले मूल्य ??) के संदर्भ में परिभाषित किया गया है, जो बताता है कि बस एक प्लेसहोल्डर है जो स्थापना के दौरान बदल जाता है।

कोई मुझे सही भी कर सकता है (कृपया!), लेकिन {-# LANGUAGE CPP #-}उस फ़ाइल के शीर्ष पर प्रज्ञा यह बताती है कि HOST_OSऔर इस तरह संकलन के पहले सी प्रीप्रोसेसर द्वारा उपयुक्त तारों को बदल दिया जाता है।


2
अगर ओपी वास्तव IOमें वहां कुछ करना चाहता है , तो uname(3)हैकेज के आसपास एक रैपर उपलब्ध है: hackage.haskell.org/package/bindings-uname
thsutton

19

सवाल एक अच्छा है। उत्तर, जैसे कि यह है, यह है कि उन मूल्यों को प्रति कार्यक्रम संकलन स्थिर है। वे अनिवार्य रूप से कार्यक्रम में संकलित हैं, और उसके बाद कभी नहीं बदलते हैं। जैसे, यदि आप उन्हें स्थिरांक के रूप में मानते हैं तो कुछ भी (जीएचसी का उपयोग करता है) टूट जाता है। और यह एक IO कार्रवाई की तुलना में एक साधारण निरंतर का उपयोग करने के लिए अधिक सुविधाजनक है।

लेकिन यह सभी तरह की विरासत का तर्क है। हास्केल एक पुरानी भाषा है। (वास्तव में नहीं, यह कई वर्षों से जावा से पुराना है।) बहुत सारे पुस्तकालयों को तर्क के साथ बनाया गया है जो अब सबसे अच्छा व्यवहार नहीं माना जाता है। ये उसी के उदाहरण हैं। एक आधुनिक पुस्तकालय उन्हें उजागर कर रहा है, जो संकलन के बाद भी परिणाम नहीं बदलते हैं, भले ही वे उन्हें IO बना देंगे। IO क्रियाओं के पीछे स्रोत स्तर पर स्थिर नहीं रहने वाली चीजों को रखना अधिक उपयोगी है, हालांकि अभी भी कुछ उल्लेखनीय अपवाद हैं, जैसे Int32- और 64-बिट प्लेटफार्मों के बीच आकार बदलना।

किसी भी मामले में ... मैं कहूंगा कि आपकी उम्मीदें ठोस हैं, और वे प्रकार ऐतिहासिक विषमताओं के परिणाम हैं।


-9

संपादित करें: यह उत्तर क्यों दिया जा रहा है, यह समझाने के लिए @interjay और @Antal Spector-Zabusky का धन्यवाद। उन्होंने लिखा

प्रलेखन थोड़ा भ्रामक है। मान GHC संकलक में हार्डकोड किए गए हैं। 48 वर्षों के बाद आप निश्चित रूप से जानते हैं कि वास्तविक कोड हमेशा दस्तावेज को रौंदता है। - interjay कल @ andy256 आप बिल्कुल सही कह रहे हैं कि दस्तावेज खराब है (वास्तव में, यही कारण है कि फ्रांसिस्को ने पहली बार में यह सवाल पूछा था), और आपका भ्रम समझ में आता है। हास्केल के बारे में बात यह है कि यदि उन स्ट्रिंग मान रनटाइम में भिन्न हो सकते हैं, तो यह एक गंभीर बग होगा - चर को बदलने की अनुमति नहीं है। यह IO प्रकार के निर्माता का महत्व है - यह एक गणना का प्रतिनिधित्व करता है जिसे "बाहरी दुनिया" तक पहुंचने की अनुमति है, और इसलिए जिसका परिणाम बदल सकता है। एक सिस्टम कॉल करना एक IO कार्रवाई का एक अच्छा उदाहरण है। … [१/२] - Antal Spector-Zabusky 9 घंटे पहले @ andy256… (एक और IO क्रिया "एक वैश्विक काउंटर को अपडेट करना" हो सकता है।) इसलिए जब हम एक स्ट्रिंग देखते हैं, तो हम जानते हैं कि यह किसी भी संचार के साथ नहीं कर सकता है। हुड के तहत ओएस। यही कारण है कि, शायद आश्चर्यजनक रूप से यदि आप हास्केल के लिए उपयोग नहीं किए जाते हैं, तो ओएस को लागू करना आसान नहीं होगा :: सिस्टम कॉल करने के लिए स्ट्रिंग - मूल हास्केल में ऐसा कोई भी मूल्य लागू नहीं है, हर प्रोग्रामर की अपेक्षाओं का उल्लंघन करेगा कि कैसे प्रोग्राम काम करते हैं, और संभावित रूप से कंपाइलर और ऑप्टिमाइज़र तक भी यात्रा करते हैं (सैद्धांतिक चिंता नहीं - वहाँ ढेर अतिप्रवाह उत्तर हैं जहां लोग एनालॉग समस्याओं में भागते हैं)। [२/२] - एंटाल स्पेक्टर-ज़बूसकी यही कारण है कि, शायद आश्चर्यजनक रूप से यदि आप हास्केल के लिए उपयोग नहीं किए जाते हैं, तो ओएस को लागू करना आसान नहीं होगा :: सिस्टम कॉल करने के लिए स्ट्रिंग - ऐसा कोई भी मूल्य बुनियादी हास्केल में लागू नहीं है, हर प्रोग्रामर की अपेक्षाओं का उल्लंघन करेगा कि कैसे प्रोग्राम काम करते हैं, और संभावित रूप से कंपाइलर और ऑप्टिमाइज़र तक भी यात्रा करते हैं (सैद्धांतिक चिंता नहीं - वहाँ ढेर अतिप्रवाह उत्तर हैं जहां लोग एनालॉग समस्याओं में भागते हैं)। [२/२] - एंटाल स्पेक्टर-ज़बूसकी यही कारण है कि, शायद आश्चर्यजनक रूप से यदि आप हास्केल के लिए उपयोग नहीं किए जाते हैं, तो ओएस को लागू करना आसान नहीं होगा :: सिस्टम कॉल करने के लिए स्ट्रिंग - मूल हास्केल में ऐसा कोई भी मूल्य लागू नहीं है, हर प्रोग्रामर की अपेक्षाओं का उल्लंघन करेगा कि कैसे प्रोग्राम काम करते हैं, और संभावित रूप से कंपाइलर और ऑप्टिमाइज़र तक भी यात्रा करते हैं (सैद्धांतिक चिंता नहीं - वहाँ ढेर अतिप्रवाह उत्तर हैं जहां लोग एनालॉग समस्याओं में भागते हैं)। [२/२] - एंटाल स्पेक्टर-ज़बूसकी और संभावित रूप से कंपाइलर और ऑप्टिमाइज़र पर भी यात्रा करें (एक सैद्धांतिक चिंता नहीं है - स्टैक ओवरफ्लो के उत्तर हैं जहां लोग एनालॉग समस्याओं में भाग लेते हैं)। [२/२] - एंटाल स्पेक्टर-ज़बूसकी और संभावित रूप से कंपाइलर और ऑप्टिमाइज़र पर भी यात्रा करें (एक सैद्धांतिक चिंता नहीं है - स्टैक ओवरफ्लो के उत्तर हैं जहां लोग एनालॉग समस्याओं में भाग लेते हैं)। [२/२] - एंटाल स्पेक्टर-ज़बूसकी

वर्तमान में इसके दो डिलीट वोट हैं। मैं उस प्रक्रिया को पूरा होने दूंगा, लेकिन यह सुझाव दूंगा कि वास्तव में इसका कुछ मूल्य है। एक साइड नोट पर, उनके स्पष्टीकरण से पता चलता है कि प्रश्न कमजोर था, और इसलिए उत्तर हैं, क्योंकि एक हास्केल नौसिखिया आसानी से उस तर्क का पालन कर सकता है जो मैंने किया था।

मूल उत्तर:

मैं हास्केल प्रोग्रामर नहीं हूं, लेकिन पहले से दिए गए दो जवाब ओपी से जुड़े दस्तावेज से मेल नहीं खाते हैं।

प्रलेखन की मेरी व्याख्या इस प्रकार है।

os :: String - यह आपको "ऑपरेटिंग सिस्टम जिस पर प्रोग्राम चल रहा है।"

मुझे उम्मीद है कि यह जानकारी प्राप्त करने के लिए एक सिस्टम कॉल जारी करेगा। क्योंकि जिस सिस्टम पर प्रोग्राम संकलित किया गया है, वह उस पर चलने वाले से भिन्न हो सकता है, यह कंपाइलर द्वारा डाला गया मान नहीं हो सकता है। यदि कोड की व्याख्या की जा रही है, तो दुभाषिया परिणाम प्रदान कर सकता है, जिसे सिस्टम कॉल के माध्यम से प्राप्त किया जाना चाहिए।

arch :: String - यह आपको "मशीन आर्किटेक्चर जिस पर प्रोग्राम चल रहा है।"

फिर से, मुझे उम्मीद है कि यह सूचना प्राप्त करने के लिए एक सिस्टम कॉल जारी करेगा। क्योंकि जिस सिस्टम पर प्रोग्राम संकलित किया गया है, वह उस पर चलने वाले से भिन्न हो सकता है, यह कंपाइलर द्वारा डाला गया मान नहीं हो सकता है।

compilerName :: String - यह आपको "हास्केल कार्यान्वयन देता है जिसके साथ कार्यक्रम संकलित किया गया था या व्याख्या की जा रही है।"

यह मान निश्चित रूप से संकलक / दुभाषिया द्वारा डाला जाता है।

compilerVersion :: String- यह आपको देता है "जिस संस्करण के compilerNameसाथ कार्यक्रम संकलित किया गया था या व्याख्या की जा रही थी।"

यह मान निश्चित रूप से संकलक / दुभाषिया द्वारा डाला जाता है।

जबकि आप इनपुट प्राप्त करने वाली पहली दो कॉल पर विचार कर सकते हैं, परिणाम ऑपरेटिंग सिस्टम द्वारा आयोजित मूल्यों से आता है। I / O आम तौर पर माध्यमिक भंडारण पहुंच को संदर्भित करता है।


3
यह हैसेल के लिए सच नहीं है। यहां कोई भी गणना अनियंत्रित है और उनका परिणाम कैश किया जा सकता है। कार्य शुद्ध होते हैं, इसलिए यदि कोई फ़ंक्शन किसी आर्गन्स को स्वीकार नहीं करता है, तो यह एक स्थिरांक की तरह होता है। एक arg के कार्य सिर्फ हैशमैप या शब्दकोशों की तरह दिखते हैं, जो कुंजी के आधार पर मूल्य की गणना करते हैं। आप बाहरी वातावरण का उपयोग नहीं कर सकते हैं, ऐसे कार्यों में syscalls करते हैं, आप एक यादृच्छिक संख्या या वर्तमान तिथि भी प्राप्त नहीं कर सकते। लेकिन अगर आप वास्तव में उस "अनुक्रमण", या पर्यावरण का उपयोग करना चाहते हैं, तो आपको IOराज्य का अनुकरण करने के लिए मोनाड का उपयोग करने की आवश्यकता है , संचालन के अनुक्रम का अनुकरण करें
यूरी

"आप बाहरी वातावरण का उपयोग नहीं कर सकते हैं, ऐसे कार्यों में syscalls करें" - निश्चित रूप से आप कर सकते हैं, खासकर अगर "आप" हास्कल कंपाइलर हैं! हास्केल कार्यान्वयन के लिए os :: Stringइसे लागू करना बहुत आसान होगा ताकि यह मूल्यांकन किए जाने पर सिस्टम कॉल करता है।
टान्नर स्विट

2
मुझे नहीं लगता कि आप हास्केल में IO के मठ के महत्व को समझते हैं।
स्नेफेल

@ स्नेफ़ेल आप निश्चित रूप से सही हैं। मैंने उत्तर देना चुना क्योंकि प्रत्येक प्रतिमान में प्रोग्रामिंग के 48 वर्षों के बाद, और विषम संकलक लिखने के बाद, प्रारंभिक उत्तर दस्तावेज़ीकरण से मेल नहीं खाते थे, और वे अभी भी नहीं करते हैं। यह स्पष्ट रूप से कहता है कि osऔर archरनटाइम पर प्राप्त किया जाता है।
andy256

1
प्रलेखन थोड़ा भ्रामक है। मान GHC संकलक में हार्डकोड किए गए हैं। 48 वर्षों के बाद आप निश्चित रूप से जानते हैं कि वास्तविक कोड हमेशा दस्तावेज को रौंदता है।
16
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.