2010-09-16 10 views
9

के साथ बिडरेक्शनल संदर्भ केस केस में एक द्वि-दिशात्मक पेड़ को कार्यान्वित करना संभव है। इस तरह यह आसान होना चाहिए लगता है, लेकिन मैंकेस कक्षा

case class Node(name:String, parent:Option[Node], children:List[Node]) 

मैं एक बच्चे को जोड़ने के लिए (और एक नया रूट मिल) चाहते स्टम्प्ड हो रही - जैसे

def addChild(n:String):Node = { 
    Node(name, parent, Node(n, Some(this), Nil)::children) 
} 

कुछ लेकिन वह नहीं होगा काम करें क्योंकि बच्चे में "पैरेंट" अब नोड को संदर्भित करेगा जो बच्चे को बच्चे के रूप में सूचीबद्ध करता है। क्या यह अपरिवर्तनीय सूचियों और केस कक्षाओं के साथ संभव है?

जवाब के आधार पर नीचे

case class Node(name: String, parent:() => Option[Node], children: List[Node]) { 
    def makeChild(name: String) = { 
    lazy val newParent:Node = Node(this.name, this.parent, kid :: this.children) 
    lazy val kid:Node = Node(name,() => Some(newParent), Nil) 
    newParent 
    } 
} 
+3

अभिभावक – Dario

उत्तर

9

दिया मैंने हाल ही में ट्विटर पर @jamesiry को :-) एक ही सवाल पूछा था।

उनका जवाब:

sealed abstract class Tree[T] 
case class Node[T](left : Tree[T], right : Tree[T]) extends Tree[T] 
case class Leaf[T](value : T, parent :() => Tree[T]) extends Tree[T] 

def make = { 
    lazy val root = Node(left, right) 
    lazy val left : Leaf[Int] = Leaf(1,() => root) 
    lazy val right : Leaf[Int] = Leaf(2,() => root) 
    root 
} 
+0

के आलसी मूल्यांकन का प्रयास करें मैंने अपना कोड अपने उपयोग के मामले में परिवर्तित कर दिया है और इसे – Jim

+0

से चिपकाया है, आपको वास्तव में किसी अन्य साइट पर रीडायरेक्ट करने के बजाय, कोड को उत्तर में पेस्ट करना चाहिए। –

+0

हां खेद है कि मैं जल्दबाजी में था क्योंकि मैला था :-(उत्तर देने के लिए फिक्टर को गायब करने के लिए धन्यवाद। – Eric

0

बस एक ध्यान दें: लगता है कि मामले कक्षाएं आप एक पेड़ का प्रतिनिधित्व करने के लिए एक अच्छा विकल्प हैं।

के बाद से मामले कक्षाएं मूल्य प्रकार के होते हैं, माता पिता के वापस जाने के लिए एक ही रास्ता माता-पिता की एक प्रति वापस जाने के लिए, पूर्ण सबट्री की एक प्रति भी शामिल है। फिर यदि आप उदाहरण के लिए अपने बच्चों की गणना करते हैं, तो आपको फिर से पूर्ण उप-प्रजातियों की प्रतियां मिलेंगी।

आप पेड़ में कुछ प्रतिस्थापन करना चाहते हैं, जैसे कुछ गहरे स्तर पर एक नोड को प्रतिस्थापित करें, फिर से एकमात्र तरीका है कि पूरे पेड़ की एक प्रति बनाएं और पुराने पेड़ को फेंक दें।

यह सब थोड़ा बेकार लगता है, लेकिन उदाहरण के लिए lift-json जेएसओएन एएसटी का प्रतिनिधित्व करने के लिए केस क्लास का उपयोग करता है, इसलिए यह एक समस्या का अधिक नहीं हो सकता है। यह सुनिश्चित नहीं है कि कॉपी करते समय स्कैला संदर्भ साझा करने पर कितना अच्छा है। शायद कोई टिप्पणी कर सकता है?

आप मामले वर्गों का उपयोग करना चाहते है, तो आलसी मूल्यांकन के साथ ऊपर जवाब सही है।