2012-09-30 18 views
5

को कैसे छोड़ सकता हूं मैं कुछ सामान्य एल्गोरिदम लागू करने वाले स्कैला के साथ मिल रहा हूं। एक बुलबुला तरह मैं इस मुद्देमैं इस नील केस

में भाग पुनः बनाने का प्रयास करते समय यहाँ शीर्ष करने के लिए मूल्य बुलबुले कि एक आंतरिक पाश के एक कार्यान्वयन है:

def pass(xs:List[Int]):List[Int] = xs match { 
    case Nil => Nil 
    case x::Nil => x::Nil 
    case l::r::xs if(l>r) => r::pass(l::xs) 
    case l::r::xs => l::pass(r::xs) 
} 

मेरे मुद्दा मामले Nil => Nil के साथ है। मैं समझता हूं कि मुझे इसकी आवश्यकता है क्योंकि मैं इस समारोह में Nil लागू कर सकता हूं। क्या यह सुनिश्चित करने का कोई तरीका है कि Nil इस तरह से एक तर्क के रूप में प्रदान नहीं किया जा सकता है जो संकलक को संतुष्ट करेगा ताकि मैं इस मामले को खत्म कर सकूं?

उत्तर

4

सूची में दो उपप्रकार, शून्य और :: है, इसलिए :: एक सूची का प्रतिनिधित्व करता है जिसमें कम से कम एक तत्व होता है।

def pass(xs: ::[Int]):List[Int] = xs match { 
    case x::Nil => x::Nil 
    case l::r::xs if(l>r) => r::pass(new ::(l,xs)) 
    case l::r::xs => l::pass(new ::(r, xs)) 
} 
+1

आह, अच्छा, मुझे इस बारे में अनजान था, क्योंकि मुझे स्कैला नहीं पता :-) –

+1

ध्यान दें कि इसका मतलब है कि आप इस फ़ंक्शन को सामान्य रूप से 'सूची [Int] 'मानों पर लागू करने में असमर्थ होंगे, क्योंकि आमतौर पर संकलक यह पता नहीं है कि किसी दिए गए 'सूची [Int] 'खाली हो जाएंगे या रनटाइम पर नहीं होंगे (सामान्य रूप से ऐसा करने से हेलिंग समस्या को हल करने की आवश्यकता होती है)। पैटर्न मिलान वह तंत्र है जिसके द्वारा एक सामान्य अज्ञात 'सूची [Int] 'मान दो अलग-अलग शाखाओं में जा सकता है, चाहे वह' शून्य' या ':: [Int]' है।इसका अर्थ यह है कि यदि आप 'सूची [Int]' के रूप में सूचियों के चारों ओर गुज़र रहे हैं, तो आपको हर बार 'पास' कहने पर उन्हें पैटर्न पैटर्न करना होगा। – Ben

+0

और आप इसे 'पास (1 :: 2 :: नील)' भी कह सकते हैं ... –

2

यह मूल प्रकार के परिष्करण के अनुरूप होगा, जहां आप एक प्रकार लिखेंगे जिसका सदस्य प्रारंभिक प्रकार का सबसेट था। फिर आप यह दिखाएंगे कि, आपके इनपुट में प्रत्येक इनपुट x के लिए, x गैर Nil था। चूंकि इसके लिए पर्याप्त मात्रा में प्रमाण की आवश्यकता होती है (आप इसे सबसेट प्रकार का उपयोग कर निर्भर प्रकार के साथ कोक में कार्यान्वित कर सकते हैं), इस स्थिति में करने के लिए बेहतर चीज एक नया प्रकार पेश करना हो सकता है, जिसमें Nil कन्स्ट्रक्टर नहीं था , केवल विपक्ष के लिए एक कन्स्ट्रक्टर और एक तत्व।

संपादित करें: स्कैला आपको इसे लागू करने के लिए सूची प्रकार पर उप-प्रकार का उपयोग करने की अनुमति देता है, तो आप इसे उस उप प्रकार का उपयोग करके विधि प्रणाली में साबित कर सकते हैं। यह अभी भी एक सबूत है, इस अर्थ में कि किसी भी प्रकार की जांच इस सबूत से मेल खाती है कि कार्यक्रम वास्तव में कुछ प्रकार में रहता है, यह केवल कुछ ऐसा है जो संकलक पूरी तरह साबित कर सकता है।

+0

डाउनवोट क्यों? मुझे इस जवाब के साथ कुछ भी गलत नहीं दिख रहा है? क्या आप इसमें कुछ तकनीकी रूप से गलत बता सकते हैं? यदि ऐसा है तो मैं इसे बदल दूंगा या हटा दूंगा। –

+0

क्योंकि आप किम स्टीबेल द्वारा प्रस्तावित चाल का उपयोग किसी भी प्रकार के जटिल प्रमाण के बिना किए गए चाल का उपयोग कर सकते हैं ... – paradigmatic

+0

@paradigmatic गलत, यह अभी भी टाइप सिस्टम में एक सबूत के अनुरूप है, सबूत subtyping के माध्यम से है, तो अभी भी एक सबूत है, यह सिर्फ एक निर्णायक तर्क में है। अभी भी एक सबूत है, लेकिन मैंने अपना जवाब आपके नोट करने के लिए संपादित किया। –

2

उस मामले तो आप बस case खंड के साथ खेल सकते में आदेश:

def pass(xs:List[Int]):List[Int] = xs match { 
    case l::r::xs if(l>r) => r::pass(l::xs) 
    case l::r::xs => l::pass(r::xs) 
    case xs => xs 
} 

पहले दो खंड केवल एक या अधिक तत्वों के साथ सूची से मेल खाएगी। अंतिम खंड कहीं और मिल जाएगा।

+1

मुझे नहीं लगता कि यह कैसे नील को पारित करता है। संकलक अभी भी लागू नहीं कर सकता है कि नील को एक के रूप में पारित किया जा सकता है तर्क reordering दिया। –

+0

यह इसे रोकता नहीं है, लेकिन प्रश्न शीर्षक में बताए गए अनुसार "शून्य मामले को छोड़ दें" की अनुमति देता है। – paradigmatic

+1

शायद शीर्षक से सहमत है, लेकिन इस कथन से सहमत नहीं है कि ओपी "यह सुनिश्चित करना चाहता है कि नील को ऐसे तरीके से एक तर्क के रूप में प्रदान नहीं किया जा सके जो संकलक को संतुष्ट करे, इसलिए मैं इस मामले को खत्म कर सकता हूं" –