2015-12-17 9 views
5

मैं हैकेल में एक कार्यात्मक भाषा के लिए एक दुभाषिया बनाने की कोशिश कर रहा हूं (मैं भाषा में नया हूं)। मैं शायद कम से कम एक अजीब मिश्रण और सुविधा का अजीब मिश्रण बना रहा हूं - कोई सार डेटा प्रकार नहीं, लेकिन मैं सजातीय सूचियां बनाने की क्षमता प्रदान करना चाहता हूं।हास्केल में एक भाषा को कार्यान्वित करना: समरूप सूची

तो मेरे मूल चर data Datum = DatInt Int | DatDbl Double | DatBool Bool हैं और मुझे एहसास हुआ है कि मुझे बिल्कुल यकीन नहीं है कि सजातीय सूचियों का प्रतिनिधित्व कैसे किया जाए। एक कन्स्ट्रक्टर List Datum जोड़ना या इस तरह का कुछ एक विषम सूची बना देगा, और प्रत्येक प्रकार के लिए एक अलग सूची बनायेगा, यानी ListInt [Int] | ListDbl [Double] सूचियों की सूचियों को रोक देगा।

एक सजातीय सूची का प्रतिनिधित्व करने के लिए सबसे अच्छा तरीका क्या होगा?

+4

के लिए आप [डाटुम]' सजातीय सूचियों के लिए, यहां तक ​​कि यह सिद्धांत रूप में विषम लोगों पकड़ रूप में अच्छी तरह सकता है। यदि आप इसके बजाय _statically_ गारंटी देना चाहते हैं कि ऐसी सूची एकरूप है, तो आपको शायद जीएडीटी और संभावित रूप से अस्तित्व के प्रकार की आवश्यकता होगी। यदि आप हास्केल के लिए नए हैं, तो शायद पहले अपने सरलतापूर्ण नो-स्टेटिक-गारंटी तरीके से अपना दुभाषिया खत्म करना बेहतर होगा। यदि आप साहसी महसूस करते हैं, तो आप फैनसीयर प्रकारों पर जाने का प्रयास कर सकते हैं। – chi

+2

दरअसल, आपका वर्तमान ढांचा आपको किसी भी प्रकार की गारंटी को एन्कोड करने का कोई मौका नहीं देता है। यदि आप 'फंक्शन' कन्स्ट्रक्टर जोड़ते हैं, तो आप यह सुनिश्चित करने में सक्षम नहीं होंगे कि फ़ंक्शंस सही प्रकारों पर लागू होते हैं। – dfeuer

+0

@chi मैं भाषा विस्तार का सहारा लेते हुए, आदर्श प्रकार की गारंटी प्रदान करना चाहता हूं। क्या यह सभी के लिए संभव है? – drowdemon

उत्तर

5

एक उपयोगी धारणा (चाहे आप सेक्सी प्रकार के लिए जा रहे हों या नहीं) एक प्रकार का टैग है। गैर-सेक्सी संस्करण से निपटने के लिए बहुत आसान है।

data Tag = IntTag 
     | DoubleTag 
     | BoolTag 
     | ListTag Tag 
    deriving (Eq, Show) 

अब आपके विभिन्न प्रकारों द्वारा इन प्रकारों का प्रतिनिधित्व किया जाता है। IntIntTag द्वारा दर्शाया गया है। Int की एक सूची ListTag IntTag द्वारा दर्शायी जाती है।

अब आप इस तरह टाइप एनोटेट भाव कुछ का प्रतिनिधित्व कर सकते हैं: `सूची

data Expr = IntLit Int 
      | DoubleLit Double 
      | BoolLit Bool 
      | ListLit Tag [Expr] 

-- Check that an expression is validly annotated 
typeCheck :: Expr -> Maybe Tag 
typeCheck IntLit{} = Just IntTag 
... 
typeCheck (ListLit tag els) 
    | all good els = Just (ListTag tag) 
    | otherwise = Nothing 
    where 
    good el = case typeCheck el of 
       Nothing -> False 
       Just res = res == tag 
+2

इसे उचित रूप से विस्तारित करने के लिए, मुझे लगता है कि वहां दो फ़ंक्शन 'चेकटाइप :: टाइप -> एक्सप्र -> हो सकता है() 'और' inferType :: Expr -> शायद टाइप' होना चाहिए, ताकि' inferType (ListLit टैग els) = mapM_ (चेक टाइप टैग) एल्स >> वापसी (ListTag टैग) 'और' चेक टाइप (ListTag टी) (ListLit टी 'els) = गार्ड (टी == टी') >> mapM_ (चेक टाइप टाइप) els; चेक टाइप _ ListLit {} = कुछ भी नहीं – user2407038

+1

संस्करण: 'अच्छा el = typeCheck el == बस टैग करें'। – chi

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