2012-02-16 4 views
9

Recently मैं this OCaml code पेश किया गया था जो हास्केल में के रूप में लिखा जा सकता है नोड्स की साझेदारी:"सही" शुद्ध कार्यात्मक दोगुना से जुड़े सूची और

data DL a = DL [a] a [a] 

create [] = error "empty list" 
create (x:xs) = DL [] x xs 

next (DL pr x (h:tl)) = DL (x:pr) h tl 
next _ = error "end of dlist" 

prev (DL (p:pr) x tl) = DL pr p (x:tl) 
prev _ = error "start of dlist" 

जो मैं हालांकि था नहीं एक उचित दोगुना से जुड़े सूची कार्यान्वयन, क्योंकि यह ट्रैवर्सल पर नया भंडारण बनाता है। OTOH वहाँ this Haskell code है:

data DList a = Leaf | Node { prev::(DList a), elt::a, next::(DList a) } 

create = go Leaf 
    where go _ []  = Leaf 
     go prev (x:xs) = current 
      where current = Node prev x next 
        next = go current xs 

हम कह सकते हैं कि यह केवल इस कोड है कि सच डीएल-सूची है?

क्या हम डीएल-सूची के नोड्स के सही साझाकरण को प्रस्तुत करने के लिए इस कोड पर भरोसा कर सकते हैं, ताकि ट्रैवर्सल पर कोई नया संग्रहण नहीं बनाया जा सके?

हास्केल में समान नाम वाले चर हमेशा एक ही "बात"की चर्चा करते हुए है या समान नाम वाले चर एक ही बात की अलग प्रति को देखें की घटनाओं को अलग कर सकते हैं? (जोर जोड़ने के लिए संपादित)।

+5

पहला कार्यान्वयन जिसे _Zipper_ के नाम से जाना जाता है; तर्कसंगत रूप से यह अकेले या दोगुनी-लिंक्ड सूचियों के लिए हो सकता है। हालांकि, यह अपने अधिकार में एक सूची कार्यान्वयन नहीं है। – ivanm

+5

यदि आप सावधानी से हास्केल रिपोर्ट पढ़ते हैं, तो आपको डेटा का प्रतिनिधित्व करने के तरीके पर एक अनुच्छेद नहीं मिल रहा है। ध्यान रखें, कि सभी प्रकार की साझाकरण कार्यान्वयन पर निर्भर है, हालांकि कुछ निश्चित सुविधाओं को लागू करने के लिए केवल कुछ समझदार तरीके हैं। – fuz

+0

इस प्रश्न के लिए धन्यवाद! मैं इसके साथ देखकर संतुष्ट नहीं हूं। – demi

उत्तर

3

मैं सुझाव दूंगा कि उत्तरार्द्ध "सही" कार्यान्वयन है, हां।

मेरे पास तथ्यों के साथ कोई तथ्य नहीं है, लेकिन जीएचसी कार्यान्वयन की मेरी समझ को देखते हुए, मुझे बाद में काम करना चाहिए कि आप एक डबल-लिंक्ड सूची को कैसे काम करेंगे।

+0

धन्यवाद! मैं निश्चित रूप से निश्चित रूप से अपने अंतिम प्रश्न के बारे में निश्चित करना चाहता हूं। :) –

+1

@WillNess मुझे विश्वास है कि यह एक कार्यान्वयन मुद्दा है, लेकिन जीएचसी एक ही चीज़ का प्रतिनिधित्व करने के लिए हुड के नीचे सूचक-आधारित प्रतिनिधित्व का उपयोग करता है (उदाहरण के लिए 'xs ++ ys' में, मूल 'ys' मान का अंत होता है नई संयुक्त सूची)। – ivanm

6

आप कल्पना कर सकते हैं कि आपकी डेटा संरचना का मेमोरी लेआउट वैक्यूम-कैरो नामक पैकेज का उपयोग कैसे करता है। cabal install vacuum-cairo साथ hackage से स्थापित करें तो आप GHCi में कुछ इस तरह से दो संरचनाओं में अंतर सत्यापित करने के लिए सक्षम होना चाहिए:

> import System.Vacuum.Cairo 
> view $ create [1..5] 

वहाँ आप देख सकते हैं नोड्स DList रूप डीएल के साथ दो सूचियों वह जगह है जहाँ का उपयोग कर साझा कर रहे हैं बीच में एक तत्व (जैसा कि बताया गया है, यह जिपर का प्रकार है)।

नोट: यह जीएचसी विशिष्ट है, एक अलग कार्यान्वयन स्मृति में डेटा का अलग-अलग प्रतिनिधित्व कर सकता है, लेकिन यह सामान्य होगा।

+0

धन्यवाद, मैं समझता हूं कि यह * कब * होना चाहिए। लेकिन यह सुझाव दिया गया था (जिस पोस्ट में मेरे प्रश्न लिंक में पहला शब्द है) साझा करना गारंटी नहीं है। फिर, संरचना कैसे होनी चाहिए, और कैसे 'कैरो' मुझे दिखाएगा, यह वास्तव में यह नहीं होगा कि यह वास्तविकता में कैसे है। मैं जानना चाहता हूं, क्या कम से कम एक गारंटी है कि वही नामित var हमेशा स्मृति में एक ही चीज़ को इंगित करता है, जो भी कार्यान्वयन में होता है? –

+0

हां, अन्यथा इस तरह का एक उदाहरण काम नहीं करेगा: '(x, xs) = y y = 10 x (लंबाई y, y) को प्रतिलिपि करें ' – Oliver

+0

मुझे लगता है कि यह अभी भी काम करेगा, क्योंकि निर्भरता प्रवाह में कोई चक्र नहीं है आपके उदाहरण में –

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