2013-01-13 27 views
5

क्या IOArray, या MArray से सामान्य रूप से एक टुकड़ा (एक उप-सरणी दृश्य) बनाने का कोई तरीका है? यही है, एक ही सरणी लेना, बस सीमाओं को सीमित करना। हस्ताक्षरएक आईओएरे (या सामान्य रूप से मैरे) को स्लाइस करना

(MArray a e m, Ix i) => a i e -> i -> i -> m (a i e) 

उदाहरण के लिए हो सकता है, सीमा (1,1000) साथ एक सरणी ले जा रहा है और एक का मानना ​​है कि केवल सीमा मूल सरणी के (500,700) साथ तत्वों के लिए पहुँच देता है बना रही है। मैंने प्रलेखन की खोज की लेकिन मुझे ऐसा कोई फ़ंक्शन नहीं मिला।

+0

तो आप श्रेणी [500..700] '_remapped_ से' [0..200] 'श्रेणी चाहते हैं, या केवल कुछ तरीकों से प्रतिबंधित होना चाहिए (उदाहरण के लिए जब आप बाहर पहुंचते हैं तो 'आईओ' अपवाद फेंकना चाहिए क्षेत्र)? यह '[(20,20) .. (40,40)] जैसी श्रेणियों के साथ बहुआयामी सरणी के लिए व्यवहार कैसे किया जाता है? – leftaroundabout

+4

मुझे ऐसा नहीं लगता है, लेकिन यदि आप Data.Vector http://hackage.haskell.org/package/vector-0.10.0.1 का उपयोग करते हैं तो आप स्लाइस निकाल सकते हैं। इसमें संलयन अनुकूलन नियम भी हैं, इसलिए यह आमतौर पर अधिक कुशल होगा। –

+0

@ बाएंअराउंडबाउट कोई रीमेपिंग आवश्यक नहीं है। असल में जो मैं चाहता हूं वह वही सरणी है जिसका 'getBounds' प्रतिबंधित सीमा की रिपोर्ट करता है (और शायद बाहरी तत्वों को accesing अपवाद फेंकता है, लेकिन यह आवश्यक नहीं है)। –

उत्तर

5

यह देखते हुए कि सरणी प्रकार कैसे कार्यान्वित किए जाते हैं, यह ऐसा कुछ नहीं है जो वास्तव में एक सरणी की विशेषता होगी, शायद यही कारण है कि इन पंक्तियों के साथ कुछ भी पहले से मौजूद नहीं है।

याद रखें कि एक सरणी स्मृति का एक संगत ब्लॉक है, इसलिए कुछ स्तर पर n तत्वों के साथ प्रत्येक सरणी (0, n-1) सीमाबद्ध है। हालांकि, शून्य से शुरू होने वाले पूर्णांक के अलावा इंडेक्स चाहते हैं, यह सामान्य है कि हास्केल मनमानी सीमाओं को परिभाषित करने और स्मृति के वास्तविक ब्लॉक के लिए 0-आधारित पूर्णांक अनुक्रमणिका में उन सीमाओं के अंदर किसी तत्व से अनुवाद करने के लिए a type class प्रदान करता है।

इससे आप जो करना चाहते हैं उसके लिए कुछ कठिनाई होती है क्योंकि यह माना जाता है कि एक सरणी के लिए सीमाएं पूरी श्रृंखला को कवर करती हैं। इसलिए यदि आप केवल एक मौजूदा सरणी की प्रतिलिपि बनाना चाहते थे जो समान स्मृति खंड का उपयोग करता था लेकिन अलग-अलग सीमाओं का उपयोग करता था, तो सूचकांक लाइन नहीं होंगे - आपके उदाहरण में, उपरे में इंडेक्स 500 मूल में इंडेक्स 1 जैसा ही होगा सरणी। अनुपयोगी।

यहां सबसे आसान तरीका आपके स्वयं के सरणी प्रकार को परिभाषित करना होगा जो मौजूदा सरणी को लपेटता है और सूचकांक का अनुवाद करने के लिए आवश्यक अतिरिक्त जानकारी संग्रहीत करता है, ताकि यह छोटी सीमा के रूप में अपनी सीमाओं को रिपोर्ट कर सके, लेकिन लपेटकर चीजों को देखता है सरणी पूरी श्रृंखला के आधार पर। इसके बाद आप हर जगह लिपटे सरणी प्रकार का उपयोग कर सकते हैं (और इसे सभी अपेक्षित उदाहरण, & सी।) नए बनाए गए सरणी के साथ बस "वास्तविक" सरणी के समान सीमाओं का उपयोग कर सकते हैं। आप इंडेक्स पर जो भी अनुवाद चाहते हैं, वह कर सकते हैं, इसलिए इस दृष्टिकोण को इंडेक्स प्रकारों के लिए सामान्यीकृत करना चाहिए जिनके पास रैखिक क्रम भी नहीं है (उदाहरण के लिए, "बहु-आयामी" सरणी tuples द्वारा अनुक्रमित)।

आप शायद अपने इंडेक्स प्रकार के चारों ओर एक रैपर को शामिल कर सकते हैं और रैपर संस्करण को एक अजीब Ix उदाहरण दे सकते हैं जो किसी भी तरह से स्वचालित रूप से अनुवादित होता है, जो आपको मौजूदा सरणी प्रकारों का उपयोग करने देता है। यद्यपि यह सही ढंग से काम करने के लिए मुश्किल होगा।

मुझे नहीं लगता कि सरणी या इंडेक्स प्रकारों को बदलने के बिना ऐसा करने का कोई तरीका है।