2011-08-07 17 views
9

यह एक बेवकूफ सवाल है जो मुझे थोड़ी देर के लिए परेशान कर रहा है। मैं एकाधिक पैरामीटर के साथ एक नया प्रकार क्यों नहीं लिख सकता,मल्टी-पैरामीटर न्यूटाइप एक टुपल के साथ फंस गया?

newtype A = A Int Int 

जबकि टुपल संस्करण ठीक है?

newtype A = A (Int, Int) 

पूर्व पैटर्न पैटर्न जैसे चीजों में बहुत अच्छा है।

+2

क्या आपने [यह] (http://www.haskell.org/haskellwiki/Newtype) पढ़ा है? –

+0

@ एन.एम., लिंक के लिए धन्यवाद, लेकिन क्या आप व्यावहारिक चिंताओं पर विस्तार कर सकते हैं? क्या इसे '(ए _ _)' मिलान के साथ करना है? मुझे समझ में नहीं आता कि ट्यूपल समकक्ष क्यों अनजान व्यवहार का कारण बनता है। – gatoatigrado

उत्तर

10

newtype A = A IntInt पर एक प्रकार isomorphic बनाता है। यही है, यह बिल्कुल Int w.r.t. जैसा व्यवहार करता है। जैसे bottom, लेकिन एक अलग नाम के तहत।

यह data A = A Int के विपरीत है जो एक उठाया प्रकार बनाता है जो Int से अलग व्यवहार करता है। एक और मूल्य जोड़ा गया है जो Int में नहीं है: A undefined (जो undefined::A से अलग है)।

अब, newtype A = A (Int, Int)(Int, Int) पर एक प्रकार isomorphic बनाता है। जो, आकस्मिक रूप से, बिल्कुल ठीक है data A = A Int Int करता है।

तो अगर हम को newtype A = A (Int, Int) के बराबर मानते हैं, तो हमारे पास क्या है? newtype A = A Int Intnewtype A = A (Int, Int) के बराबर है जो data A = A Int Int के बराबर है।

newtype A = A Int Intdata A = A Int Int के बराबर है (जो पहली जगह में newtype होने के पूरे मुद्दे है) (ताकि newtype इस मामले में अनावश्यक है), लेकिन

newtype A = A Intdata A = A Int के बराबर नहीं है।

तो हमें यह निष्कर्ष निकालना होगा कि newtype A = A (Int, Int) के समतुल्य होने के कारण अनावश्यकता और असंगतता पैदा करता है, और हम इसे अनुमति देने से बेहतर नहीं हैं।

शायद कोई रास्ता नहीं newtype A = A Int Int कुछ अन्य अर्थ है जो इन विसंगतियों से मुक्त है देने के लिए है (वरना यह पाया जाता है और इस्तेमाल किया मुझे लगता है किया जाएगा;)

7

क्योंकि एक newtype, मोटे तौर पर कहा जाए तो type तरह रनटाइम पर काम करता है और संकलन समय पर data की तरह। प्रत्येक data परिभाषा संकेत की एक अतिरिक्त परत जोड़ती है - जो, सामान्य परिस्थितियों में, एक और विशिष्ट जगह है, जहां किसी थंक के रूप में कुछ छोड़ा जा सकता है - उसके मूल्यों के आस-पास, जबकि newtype नहीं है। newtype पर "कन्स्ट्रक्टर" मूल रूप से केवल एक भ्रम है।

कोई भी चीज जो एक में एक से अधिक मान को जोड़ती है, या कि कई मामलों के बीच एक विकल्प देता है, जरूरी अविवेक की एक परत का परिचय है कि व्यक्त करने के लिए है, तो newtype A = A Int Int की तार्किक व्याख्या "एक साथ उन्हें पकड़" कुछ भी नहीं के साथ दो कट Int मूल्यों होगा । newtype A = A (Int, Int) के मामले में अंतर यह है कि ट्यूपल स्वयं संकेतक की अतिरिक्त परत जोड़ता है।

data A = A Int Int बनाम data A = A (Int, Int) के साथ इसकी तुलना करें।पूर्व दो परतों (A कन्स्ट्रक्टर) को दो Int एस के आस-पास जोड़ता है, जबकि बाद में ट्यूपल के चारों ओर एक ही परत जोड़ता है, जो स्वयं Int एस के आसपास एक परत जोड़ता है।

संकेतक की प्रत्येक परत भी आम तौर पर एक जगह जोड़ती है जहां कुछ हो सकता है, इसलिए प्रत्येक रूप के लिए संभावित मामलों पर विचार करें, कहां? एक गैर-नीचे मूल्य के लिए खड़ा है:

  • newtype A = A (Int, Int) के लिए: , (⊥, ?), (?, ⊥), (?, ?)

  • data A = A Int Int के लिए: , A ⊥ ?, A ? ⊥, A ? ?

  • data A = A (Int, Int) के लिए: , A ⊥, A (⊥, ?), A (?, ⊥), A (?, ?)

जैसा कि आप उपर्युक्त से देख सकते हैं, पहले दो समकक्ष हैं।


एक अंतिम नोट पर, यहाँ कितना newtypedata से अलग है की एक मजेदार प्रदर्शन है। इन परिभाषाओं पर विचार करें:

data D = D D deriving Show 
newtype N = N N deriving Show 

क्या संभावित मान, सभी संभव ⊥s सहित, इनमें से प्रत्येक क्या ज़रूरत है? और आपको क्या लगता है कि नीचे दिए गए दो मान होंगे?

d = let (D x) = undefined in show x 
n = let (N x) = undefined in show x 

उन्हें जीएचसी में लोड करें और पता लगाएं!

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