हास्केल आपको मौजूदा चर को संशोधित करने की अनुमति नहीं देता है। हालांकि, यह आपको वैरिएबल नामों का पुन: उपयोग करने की अनुमति देता है, और यह सब कुछ हो रहा है। एक तरीका यह देखने के लिए GHCi पूछने के लिए, :i[nfo]
निर्देश, जहां चर घोषित किया गया था का उपयोग कर रहा है:
Prelude> let a = 1
Prelude> :i a
a :: Num a => a -- Defined at <interactive>:2:5
Prelude> let a = 2
Prelude> :i a
a :: Num a => a -- Defined at <interactive>:4:5
ये वास्तव में दो पूरे अलग, अलग चर, जो सिर्फ एक ही नाम के नाम से जाना हो रहे हैं! तुम सिर्फ a
के लिए कहते हैं, तो नए परिभाषा हो जाएगा “ वरीय ”, लेकिन जैसा कि टिप्पणी में ची ने टिप्पणी की एक पुरानी अभी भी वहाँ – एक तरह से यह देखने के लिए, एक समारोह में a
उपयोग करने के लिए है:
Prelude> let a = 2
Prelude> :i a
a :: Num a => a -- Defined at <interactive>:4:5
Prelude> let f x = a + x
Prelude> let a = 3
Prelude> f (-2)
0
f
को कभी भी यह ध्यान देने की आवश्यकता नहीं है कि आपने एक नया चर परिभाषित किया है जिसे a
भी कहा जाता है; इसके परिप्रेक्ष्य से a
एक अपरिवर्तनीय चर था जो हमेशा रहता है।
जीएचसीआई बाद की परिभाषा को क्यों पसंद करता है, इस बारे में कुछ बात करने लायक है। यह नहीं अन्यथा हास्केल कोड में होता है; विशेष रूप से यदि आप निम्न मॉड्यूल संकलित करने के लिए कोशिश में, यह बस एक त्रुटि के विषय में डुप्लिकेट परिभाषा देता है:
a = 1
a = 2
main :: IO()
main = print a
कारण यह है कि कुछ इस तरह GHCi में अनुमति दी है कि यह हास्केल मॉड्यूल से अलग काम करता है। जीएचसीआई आदेशों का अनुक्रम वास्तव में आईओ मोनैडऔर डैगर में कार्यों का अनुक्रम बनाता है;; यानी कार्यक्रम अब
main :: IO()
main = do
let a = 1
let a = 2
print a
होना चाहिए था, अगर आप monads के बारे में सीखा है आपको पता चल जाएगा कि इस के लिए
main =
let a = 1 in (let a = 2 in (print a))
बस वाक्यात्मक चीनी है और यह वास्तव में क्यों के लिए महत्वपूर्ण बिट है आप a
नाम का पुनः उपयोग कर सकते हैं: दूसरा, a = 2
, को पहले की तुलना में एक संक्षिप्त दायरे में रहता है। तो यह अधिक स्थानीय है, और स्थानीय परिभाषाओं को प्राथमिकता है।चाहे यह एक अच्छा विचार है थोड़ा बहस योग्य है; इसके लिए एक अच्छा तर्क आप की तरह
greet :: String -> IO()
greet name = putStrLn $ "Hello, "++name++"!"
एक कार्य हो सकता है और यह काम कर रहा है सिर्फ इसलिए किसी को कहीं और
name :: Car -> String
name car | rollsOverAtRightTurn car = "Reliant Robin"
| fuelConsumption car > 50*litrePer100km
= "Hummer"
| ... = ...
इसके अलावा परिभाषित करता है बंद नहीं होगा कि है, यह वास्तव में बहुत उपयोगी है कि आप “ को फिर से परिभाषित कर सकते हैं ” जीएचसीआई में चारों ओर बेवकूफ बनाते समय चर, भले ही यह एक उचित कार्यक्रम में सामान को फिर से परिभाषित करने के लिए एक अच्छा विचार है, जो लगातार व्यवहार दिखाना है।
और डैगर; जैसा कि डेफ्यूयर टिप्पणी करता है, यह पूरी सच्चाई नहीं है। आप जीएचसीआई में कुछ चीजें कर सकते हैं जिन्हें IO
डू-ब्लॉक में अनुमति नहीं है, विशेष रूप से आप data
प्रकार और class
es परिभाषित कर सकते हैं। लेकिन किसी भी सामान्य कथन या चर परिभाषा अधिनियम के रूप में यह IO
monad में थे।
जो मेरे रैपल में काम नहीं करता है ... – Netwave
'a = 1 डालने का प्रयास करें; एक = 2' '.hs' फ़ाइल के अंदर और इसे' ghc' के साथ संकलित करें ... – Bakuriu
जीएचसीआई कमांड आईओ क्रियाएं हैं, इसलिए ऐसा लगता है कि आपके द्वारा टाइप की गई हर चीज 'डू' ब्लॉक के अंदर थी। जिसका अर्थ है कि उसी नाम के बाद के असाइनमेंट नेस्टेड 'चलो, आप * छाया * पुरानी बाध्यकारी की तरह हैं। – Bakuriu