2015-06-03 20 views
6

स्काला में, मैं परिभाषित कर सकते हैं एक Algebraic Data Type:प्रकार निर्माता के रूप में वापसी प्रकार

scala> sealed trait Maybe[A] 
defined trait Maybe 

scala> case class Just[A](x: A) extends Maybe[A] 
defined class Just 

scala> case object NothingHere extends Maybe[Nothing] 
defined object NothingHere 

यह एक समारोह, f वापस जाने के लिए, Maybe[A] की वापसी प्रकार के साथ संभव है।

scala> def f[A](x: A): Maybe[A] = Just(x) 
f: [A](x: A)Maybe[A] 

हालांकि, यह भी निर्दिष्ट करने के लिए है कि एक Just[A] दिया जाता है संभव है।

scala> def f[A](x: A): Just[A] = Just(x) 
f: [A](x: A)Just[A] 

अब मैं हास्केल में समान व्यायाम करेंगे:

Prelude> data Option a = None | Some a deriving Show 
Prelude> let f x = Some x :: Option Int 
Prelude> f 10 
Some 10 

लेकिन, मैं एक प्रकार निर्माता की वापसी प्रकार निर्धारित नहीं कर सकते।

Prelude> let f x = Some x :: Some Int 

<interactive>:10:21: 
    Not in scope: type constructor or class `Some' 
    A data constructor of that name is in scope; did you mean DataKinds? 
Prelude> let f x = None :: None 

सरल अंतर यह है कि स्काला के Just एक वर्ग है, यानि कि एक वैध वापसी प्रकार है? जबकि, हास्केल में, प्रकार का निर्माता रिटर्न प्रकार नहीं हो सकता है?

उत्तर

10

अंतर यह है कि स्कैला ने एडीटी को कैसे लागू किया। स्कैला केस कक्षाओं का उपयोग करता है जो ओओपी शैली में एक विशेषता का विस्तार करते हैं, इसलिए प्रत्येक मामले का अपना प्रकार होता है, जबकि हास्केल के पास एक ही प्रकार के लिए कई कन्स्ट्रक्टर होते हैं। चूंकि वे अलग-अलग प्रकार नहीं हैं लेकिन अनिवार्य रूप से केवल अलग-अलग फ़ंक्शंस हैं, इसलिए आप उन्हें प्रकार के स्तर पर अंतर नहीं कर सकते हैं। ऐसे एक्सटेंशन हैं जो आपको उस प्रकार के स्तर के भेद को बनाने की कुछ क्षमता देते हैं, लेकिन यह स्कैला के समान ही नहीं होगा। और स्कैला के प्रकार प्रणाली में हास्केल के प्रकार प्रणाली को फिट करने की कोशिश शायद संभवतः विचारों का सबसे अच्छा नहीं है।

संक्षेप में, स्कैला विरासत के एक प्रकार का उपयोग करके एडीटी का अनुमान लगाती है, जबकि हास्केल में केवल एडीटी है।

+3

ऐसे एक्सटेंशन हैं जो आपको _similar_ क्षमता देते हैं, लेकिन यह काफी महत्वपूर्ण है कि हास्केल के पास कोई सबक्लासिंग नहीं है, इसलिए आप सकारात्मक रूप से एक ही काम नहीं कर सकते हैं .. – leftaroundabout

+0

@ बाएंराउंडबाउट ने शब्द को थोड़ा और बदल दिया ताकि यह स्पष्ट हो सके कि मैं था उन एक्सटेंशन का जिक्र करते हुए जो आपको रचनाकारों को प्रकार के स्तर पर अलग करने देते हैं, लेकिन यह स्कैला के समान नहीं है। सोचो अब यह और अधिक स्पष्ट बनाता है? – bheklilr

0

भेलकिर और बाएंअराउंडबाउट ने इंगित किया है कि आप इसे हास्केल में क्यों नहीं कर सकते: उपप्रकारों की कोई धारणा नहीं है।

लेकिन ध्यान दें कि एडीटी के साथ अक्सर विकल्प होते हैं जो आपको एक ही प्रभाव प्राप्त करने की अनुमति देते हैं। इस मामले में, एक उम्मीदवार तकनीक Either साथ संयोजन के रूप में उपयोग करने के लिए the Void type होगा:

import Data.Void 

f :: Int -> Either Void Int 
f x = Right x 

Void एक प्रकार कोई परिभाषित मूल्यों किया है। इसलिए यदि आप Either Void a टाइप करते हैं, तो इसका मतलब है कि चूंकि x :: Void कोई मान नहीं है, कोई भी Left x :: Either Void a फ़ॉर्म का कोई भी मूल्य कभी भी नहीं बना सकता है। (अपवाद अगर x एक गारंटीकृत nonterminating मूल्य है, लेकिन we customarily ignore that possibility है।)

इसका मतलब है कि एक Either Void a, प्रपत्र Right a की हमेशा होता है तो उदाहरण के लिए, तो आप इस समारोह लिख सकते हैं:

-- | Extract the @[email protected] from @Either Void [email protected] 
extract :: Either Void a -> a 
extract (Left x) = absurd x 
extract (Right a) = a 

absurd x मूल रूप से इस तरह काम करता है: x :: Void का मतलब है कि वास्तव में x के लिए वास्तव में कोई मान नहीं हो सकता है, फिर absurd :: Void -> a, इसके प्रकार के अनुसार, एक ऐसा कार्य है जिसे कभी कॉल करना असंभव है। जिस तरह से सिस्टम सिस्टम काम करता है इसका मतलब यह है कि कॉलर की अपेक्षा की जाने वाली किसी भी प्रकार को वापस करने का दावा किया जा सकता है। कुछ और चर्चाओं के लिए this question देखें (हालांकि शायद थोड़ा उन्नत)।

+0

शायद मुझे कुछ याद आ रहा है, लेकिन क्यों न सिर्फ 'ए' वापस लौटाएं? – dfeuer

+0

@ डीफ्यूअर: डी ओह! हाँ, मैं उस बिट को हटा रहा हूं ... –

+0

मेरा मतलब यह था कि, यदि आप बोतलों को बाहर करते हैं, तो 'या तो शून्य ए' 'ए' के लिए isomorphic है। उन सभी परेशानियों पर क्यों जाना है? – dfeuer

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