2015-08-24 4 views
10

तो मुझे एक ऐसा प्रकार चाहिए जो नोड-प्रकारों के सेट वाले वृक्षों का प्रतिनिधित्व करता हो। मैं उन प्रकारों को भी पसंद करूंगा जो ओवरलैपिंग सेट पर परिभाषित समान पेड़ का प्रतिनिधित्व करते हैं। यह टाइप एएसटी समस्या का एक और संस्करण है। का कहना है कि नोड प्रकार के अपने पूल है:हास्केल में एक पॉलिमॉर्फिक पेड़ टैग करते समय मैं सिंटैक्टिक अव्यवस्था को कैसे कम कर सकता हूं?

data Lit = Lit Int 
data Var = Var String 
data Hole = Hole Int 

एक पार्स पेड़ Lit या Var रों लेकिन कोई Hole रों हो सकते हैं। टेम्पलेट नामक एक दूसरे प्रकार के पेड़ में Lit एस, Var एस या Hole एस शामिल हो सकता है।

चीजों को सरल रखने के लिए Add नामक एक प्रकार का रिकर्सिव नोड है।

data Parse = A Lit | B Var 
data Template = C Lit | D Var | E Hole 
data Tree a = Leaf a 
      | Add (Tree a) (Tree a) 

तो अब मैं डेटा घोषणा कर सकते हैं, और मैं अब भी उस पर पैटर्न मैचों की, समस्या सिर्फ वाक्यात्मक अव्यवस्था है सकते हैं।

ParseLit = A . Lit 
TempLit = C . Lit 

जाहिर कंस्ट्रक्टर्स (नहीं प्रकार) की रचनाओं के लिए उपनाम हास्केल में कानूनी नहीं है:

aParse = Add (A Lit 3) (B Var "x") 
aTemplate = Add (C Lit 4) (E Hole 3) 
fun (Add (A lit) (B var) = ... 

क्या मैं चाहूँगा कुछ चीनी के समान है। लेकिन जितना संभव हो उतना बॉयलर-प्लेट से बचने के लिए इसे लिखने का सबसे साफ तरीका क्या है?

उत्तर

14

PatternSynonyms भाषा एक्सटेंशन यहां सहायता कर सकता है। यह आप पैटर्न के लिए उपनाम निर्दिष्ट कर सकते हैं: द्विदिश (उदाहरण की तरह) और दिशाहीन:

{-# LANGUAGE PatternSynonyms #-} 

pattern ParseLit x = A (Lit x) 

someFunc :: Parse -> Int 
someFunc p = case p of 
    ParseLit x -> x 
    _ -> 0 

पैटर्न समानार्थक शब्द के दो जायके हैं। बिडरेक्शनल वाले का भी कन्स्ट्रक्टर के रूप में उपयोग किया जा सकता है:

*Main> :t ParseLit 
ParseLit :: Int -> Parse 

*Main> ParseLit 77 
+0

ओह वाह। यह वहीं है जिसे मैं ढूंढ रहा था। धन्यवाद। – Amoss

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