2016-04-15 4 views
5

अपोहक इस समारोहडायलज़र इस सरल त्रुटि को क्यों नहीं पकड़ता है?

-spec myfun(integer()) -> zero | one. 
myfun(0) -> zero; 
myfun(1) -> one; 
myfun(2) -> other_number. 

की वापसी प्रकार में विसंगति का संकेत नहीं करता है, लेकिन यह अंतिम पंक्ति जा रहा है

myfun(_) -> other_number. 

के मामले में पता लगाता है क्यों यह इतना है? ऊपर एक बहुत ही सरल मामले होना चाहिए, मैं belive ...

धन्यवाद

उत्तर

5

प्रकार के "क्यों अपोहक नहीं है ..." क्योंकि यह होना करने के लिए डिजाइन किया गया है कि "सवाल करने के लिए आसान जवाब हमेशा सही "या" क्योंकि यह कभी वादा नहीं करता है कि यह सब कुछ या कुछ विशिष्ट पकड़ लेगा "।


अधिक जटिल उत्तर के लिए, आपको अपना प्रश्न आगे निर्दिष्ट करने की आवश्यकता है। अगर मैं एक मॉड्यूल में अपने उदाहरण लिखें:

-module(bar). 

-export([myfun1/1, myfun2/1]). 

-spec myfun1(integer()) -> zero | one. 

myfun1(0) -> zero; 
myfun1(1) -> one; 
myfun1(2) -> other_number. 

-spec myfun2(integer()) -> zero | one. 

myfun2(0) -> zero; 
myfun2(1) -> one; 
myfun2(_) -> other_number. 

और यह Dialyze:

$ dialyzer bar.erl 
    Checking whether the PLT /home/stavros/.dialyzer_plt is up-to-date... yes 
    Proceeding with analysis... done in 0m0.64s 
done (passed successfully) 

... न तो विसंगति 'का पता चला' है, कारण न तो एक "त्रुटि" है। यह सिर्फ मामला है कि कोड कुछ तरीकों से अधिक सामान्य (अतिरिक्त मूल्यों को वापस कर सकता है) और कुछ तरीकों से अधिक प्रतिबंधक (प्रत्येक पूर्णांक को संस्करण 1 के लिए, संस्करण 1 के लिए संभाल नहीं सकता है)।

दूसरे संस्करण की समस्या -Woverspecs साथ पाया जा सकता है:

$ dialyzer -Woverspecs bar.erl 
    Checking whether the PLT /home/stavros/.dialyzer_plt is up-to-date... yes 
    Proceeding with analysis... 
bar.erl:11: Type specification bar:myfun2(integer()) -> 'zero' | 'one' is a subtype of the success typing: bar:myfun2(_) -> 'one' | 'other_number' | 'zero' 
done in 0m0.58s 
done (warnings were emitted) 

चेतावनी बताते हैं वास्तव में कल्पना कोड से अधिक प्रतिबंधात्मक है।

दोनों समस्याओं भी अत्यंत असामान्य -Wspecdiffs द्वारा पता लगाया जा सकता है: आपरेशन के

$ dialyzer -Wspecdiffs bar.erl 
    Checking whether the PLT /home/stavros/.dialyzer_plt is up-to-date... yes 
    Proceeding with analysis... 
bar.erl:5: Type specification bar:myfun1(integer()) -> 'zero' | 'one' is not equal to the success typing: bar:myfun1(0 | 1 | 2) -> 'one' | 'other_number' | 'zero' 
bar.erl:11: Type specification bar:myfun2(integer()) -> 'zero' | 'one' is a subtype of the success typing: bar:myfun2(_) -> 'one' | 'other_number' | 'zero' 
done in 0m0.61s 
done (warnings were emitted) 

न तो -Woverspecs है और न ही -Wspecdiffs मोड अपोहक के प्रकार विश्लेषण और प्रकार के सामान्यीकरण कर सकते हैं के रूप में, प्रोत्साहित किया जाता है, तो "कुछ एक में निर्दिष्ट किया जा रहा अधिक प्रतिबंधक तरीका "सामान्यीकरण का परिणाम हो सकता है।

यह भी हो सकता है कि आप इन कार्यों को केवल 0 और 1 के साथ तर्क के रूप में बुलाएं, इस मामले में spec 'ठीक' है।

+0

क्या आप "डायलजर के प्रकार के विश्लेषण के प्रकार को सामान्यीकृत कर सकते हैं और सामान्यीकृत करेंगे ..." अधिक स्पष्ट रूप से, उदाहरण के साथ? – mljrg

+0

उदाहरण 1: कहें कि आपके पास एक और फ़ंक्शन कॉल है, जिसमें एक तर्क है जो हमेशा "<= 0" होगा। डायलज़र हमेशा यह अनुमान नहीं लगाएगा कि इस तरह के कॉल का नतीजा केवल 'शून्य' हो सकता है। उदाहरण 2: कहें कि आपके पास एक ऐसा कार्य है जो सभी संख्याओं के लिए भी काम करता है। डायलज़र अनुमान लगाएगा कि यह सभी पूर्णांक के लिए काम करता है। और इतने पर ... – aronisstav

+0

तो, यदि संभावित समस्या की उपस्थिति (प्रत्यक्ष या अप्रत्यक्ष रूप से) का पता लगाने के लिए विकल्प '-वॉवर्सपीक्स' और '-Wspecdiffs' का उपयोग किया जा सकता है, तो उनका उपयोग क्यों निराश होता है? मुझे लगता है कि आप या तो इन विकल्पों को हटा देते हैं, या लोग उन्हें इस्तेमाल करते हैं ... – mljrg

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