2014-07-25 11 views
6

मैं हैकेल में आलसी मूल्यांकन के बारे में पढ़ रहा हूं और एक प्रश्न है। उदाहरण के लिए हम निम्नलिखित संगणना है:डेटा संरचनाओं के आलसी मूल्यांकन

Prelude> let x = 1 + 1 :: Int 
Prelude> let y = (x,x) 

और x का मूल्य प्राप्त करने के बाद:

Prelude> :sprint x 
x = _ 

यह unevaluated है। ठीक है, अब हम y के मूल्य मिलता है:

Prelude> :sprint y 
y = (_,_) 

यह बहुत unevaluated है, क्योंकि yx and it's unevaluated पर निर्भर करता है। अब हम एक ही उदाहरण लेकिन ::Int बिना की कोशिश करते हैं:

Prelude> let x = 1 + 1 
Prelude> let y = (x, x) 
Prelude> :sprint y 
y = _ 

क्यों y मूल्य _ बजाय (_, _) है जब हम ::Int बिना कोशिश कर रहे हैं?

मैं देख रहा हूँ कि वे विभिन्न प्रकार है:

Prelude> let x = 1 + 1 
Prelude> :t x 
x :: Num a => a 
Prelude> let x = 1 + 1 :: Int 
Prelude> :t x 
x :: Int 

लेकिन क्यों y के मूल्यों पर निर्भर?

धन्यवाद।

+1

अब वास्तव में मजेदार भाग के लिए, 'x' होने के प्रकार' Num a => a' के साथ, आप 'x' और 'y' दोनों का पूर्ण मूल्यांकन करने के बाद क्या होता है? उनके 'स्प्रिंट' प्रतिनिधित्व का क्या होता है? – bheklilr

+0

@bheklilr, हाँ, बहुत रोचक। मैंने बनाया: 'x' और' y' के लिए 'seq', वे मान प्रिंट करते हैं, लेकिन: स्प्रिंट प्रिंट्स' _' – 0xAX

+1

इसका प्रकार "x" का मूल्यांकन करने का भी अर्थ है जब इसका प्रकार 'Num a => a' है ? संकलक कैसे जानता है कि इसके साथ क्या करना है? यह कहने में सक्षम कैसे है कि 'x' का मान '2' है जब यह नहीं पता कि' + 'का उपयोग करने के लिए कौन सा कार्यान्वयन है? मैं 'Int' के आस-पास अपना खुद का नया प्रकार कार्यान्वित कर सकता हूं जिसे '(MyInt x) + (MyInt y) = MyInt (x-y)' के रूप में परिभाषित किया गया है, तो जीएचसी क्या कर रहा है ताकि वह 'x' प्रिंट करने में सक्षम हो सके। 'मूल्य' 2' है? – bheklilr

उत्तर

7

क्या हो रहा है जब आप x निर्दिष्ट किया है प्रकार Num a => a है, संकलक संभवतः Num का जो उदाहरण है जब 1 + 1 प्रदर्शन का उपयोग करने में पता नहीं कर सकते हैं। इसके बजाय यह डिफ़ॉल्ट रूप से उपयोग करता है। जीएचसी कुछ प्रकार के वर्गों के लिए डिफ़ॉल्ट प्रकार को परिभाषित करता है ताकि जब यह निर्धारित करने के लिए कोई ठोस तरीका न हो कि इसका उपयोग करने के लिए ठोस प्रकार अभी भी त्रुटियों को उठाए बिना सार्थक परिणाम दे सकता है। तो जब आप देखते हैं

> let x :: Num a => a 
|  x = 1 + 1 
> x 
2 
> :sprint x 
x = _ 

इसका कारण यह है GHCi Num के लिए अपने डिफ़ॉल्ट प्रकार के रूप में Integer चुनता है, लेकिन जब यह इस कार्रवाई निष्पादित करता है यह x की स्मृति स्थान में परिणाम की दुकान नहीं है, के बाद से वहाँ नहीं है एक यह जानने का तरीका कि क्या यह सही जवाब भी है। यही कारण है कि आप :sprint से देखते हैं, इसने वास्तव में x :: Num a => a का मूल्यांकन नहीं किया है, इसका मूल्यांकन x :: Integer है। तुम भी इस के साथ गड़बड़ खुद डिफ़ॉल्ट कर सकते हैं:

> newtype MyInt = MyInt Int deriving (Eq) 
> 
> instance Show MyInt where 
|  show (MyInt i) = show i 
> instance Num MyInt where 
|  (MyInt x) + (MyInt y) = MyInt (x - y) 
|  fromInteger = MyInt . fromInteger 
> 
> default (MyInt) 
> x 
0 

तो अब हम कि 1 + 1 = 0 कहा गया है! ध्यान रखें कि जीएचसी की इस कार्यक्षमता के लिए शायद आपके पास कभी भी उपयोग नहीं होगा, लेकिन इसके बारे में जानना अच्छा है।

+0

महान स्पष्टीकरण +1 और धन्यवाद – Carsten

+0

बीटीडब्ल्यू: मेरे सिस्टम पर जीएचसीआई 'x' से' 2 :: इंटीजर' सेट करेगा इसका मूल्यांकन करने के बाद! – Carsten

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