2012-08-30 16 views
5

मैं ऑनलाइन पुस्तक "learn you some erlang" के साथ पढ़ रहा हूं और मेरी समझ की जांच करने के लिए कुछ अभ्यास करने की कोशिश कर रहा हूं।क्यों डायलज़र मुझे बताता है कि इस मजेदार अनुबंध डोमेन को ओवरलैप कर रहा है?

मैं में अध्याय प्रकार निर्दिष्टीकरण और Erlang, फीफो उदाहरण पर कुछ संशोधन किए गए, (एक फीफो जहां सभी तत्वों को एक ही प्रकार टी का होना चाहिए)

एक "typed_fifo (टी)" को परिभाषित करने की कोशिश कर रहा

मेरी प्रकार विनिर्देश हैं:

-spec empty (typed_empty_fifo()) -> true;

(typed_nonempty_fifo(_)) -> false. 

empty({fifo, [], []}) -> true;

empty({fifo, A, B}) when is_list(A), is_list(B) -> false.

dialyze:

-type typed_empty_fifo() :: {fifo, [], []}.

-type typed_nonempty_fifo(A) :: {fifo, nonempty_list(A), list(A)} | {fifo, [],nonempty_list(A) }.

-type typed_fifo(A) :: typed_empty_fifo() | typed_nonempty_fifo(A).

और जब मैं निम्नलिखित समारोह कल्पना में इसका इस्तेमाल करते हैं आर बताता है कि यह ओवरलैपिंग डोमेन की वजह से विनिर्देश को अनदेखा कर देगा।

क्या कोई मुझे बता सकता है कि मैं कहां गलती करता हूं?

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

यह वास्तव में अजीब है, क्योंकि जब मैं बीआईएफ लंबाई/1 का उपयोग करता हूं, तो यह बैडग के कारण विफल हो सकता है!

23> L=[1,2|3]. ==> [1,2|3]

24> is_list(L). ==> true

25> length(L). ==> exception error: bad argument

in function length/1 

    called as length([1,2|3]) 

धन्यवाद

उत्तर

3

आपके प्रकार और विशिष्टता में कुछ भी गलत नहीं है। समस्या यह है कि डायटिज़र में टाइपटाइप का उपयोग प्रकारों के प्रतिनिधित्व के लिए किया जाता है, जो आप प्रदान कर रहे हैं उतना सटीक नहीं रखते हैं। विशेष रूप से, संघ: {fifo, nonempty_list(A), list(A)} | {fifo, [],nonempty_list(A) } "कुचल" है {fifo, list(A), list(A)} में, के रूप में tuples ही arity (3) और पहली परमाणु तत्व (fifo) है। टाइप विश्लेषण अधिक कुशल बनाने के लिए डायलज़र आमतौर पर अधिक अनुमान लगाता है (जैसा कि आप here भी देख सकते हैं)। आप इस चेतावनी को सुरक्षित रूप से अनदेखा कर सकते हैं।

आपके दूसरे प्रश्न के लिए, is_list/1 केवल यह जांचता है कि क्या इस शब्द का पहला कन्स्ट्रक्टर इसके तर्क के रूप में पारित किया गया है, एक विपक्ष सेल है। यहां तक ​​कि is_list([1|2])true देता है।

आप यह सुनिश्चित करें कि एक तर्क एक उचित सूची आप इस प्रकार का case अभिव्यक्ति में एक कस्टम समारोह का उपयोग कर सकते है चाहते हैं:

case is_proper_list(L) of 
    true -> ...; 
    false -> ... 
end 

is_proper_list([]) -> true; 
is_proper_list([_|L]) -> is_proper_list(L); 
is_proper_list(_) -> false. 

हालांकि यह एक गार्ड में नहीं रखा जा सकता। गार्ड में आप नीचे दी गई टिप्पणी में सुझाए गए एक का उपयोग कर सकते हैं (length(L) >= 0)।

+0

धन्यवाद अरोनिस। मुझे लगता है कि मैं डायलजर प्रदान करने का इरादा रखता हूं। मैं यह पता लगाने की कोशिश कर रहा हूं कि उन spec परिभाषाओं का उपयोग करने का क्या लाभ हो सकता है, डायलज़र क्या कर सकता है, और मेरे लिए क्या प्रयास है। कम से कम मैं इस मुद्दे को अनुचित सूची के साथ खोजता हूं। वैसे, मैं अभी भी अपने दूसरे प्रश्न का हल ढूंढ रहा हूं। मेरे पास झुकाव है कि मज़ेदार गार्ड में एक परीक्षण जैसे: is_list (X) और भी लम्बाई (एक्स)> -1 काम करता है। लेकिन यह एक समारोह के अंदर दुर्घटनाग्रस्त हो जाता है। – Pascal

+0

मैंने एक संभावित समाधान के साथ जवाब संपादित किया है। ओह और मेरा पहला नाम स्टेव्रोस है! :-) – aronisstav

0

अपने दूसरे प्रश्न के बारे में, list के साथ काम करने के लिए सही तरीका है:

1> L = [1,2|[3]]. 
[1,2,3] 
2> is_list(L). 
true 
3> length(L). 
3 

ध्यान दें, कि [Head|Tail] अंकन आप Taillist (नहीं int) होने के लिए से की आवश्यकता है ।

+0

जवाब के लिए धन्यवाद। मुझे पता था, लेकिन मैंने सवाल का अंत बहुत तेज़ लिखा था। अनुचित सूची बनाने के लिए मैंने इस असाइनमेंट को उद्देश्य पर किया था।तथ्य यह है कि मेरा फीफो मॉड्यूल केवल वैध फीफो बनाएगा, लेकिन कुछ भी नहीं रोकता है कि एक और मॉड्यूल अनुचित सूची पर बनाया गया एक फीफो बनाता है, और मैं इसे देखना चाहता हूं (पाठ्यक्रम के अभ्यास के लिए, वास्तविक जीवन में मैं इसका उपयोग करता हूं sdlib एक ...) – Pascal

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