2012-01-30 19 views
5

यहां मेरी पुस्तक से कोड का एक स्निपेट है, और मुझे यकीन नहीं है कि मिलान कैसे काम करता है क्योंकि ऐसा लगता है कि पहला मामला सब कुछ मेल खाता है। यहां चेतावनियां हैं ओकम्ल मुझ पर फेंकता है:ओकैमल पैटर्न `शून्य -> ​​शून्य` क्यों सबकुछ मेल खाता है?

# let zero = 0;; 
# let one = 1;; 
# let rec fib i = 
match i with 
zero -> zero 
| one -> one 
| j -> fib (j - 2) + fib (j - 1);; 
Characters 57-60: 


Warning: this match case is unused. 
Characters 74-75: 
Warning: this match case is unused. 
| one -> one 
^^^ 
| j -> fib (j - 2) + fib (j - 1);; 
^ 
val fib : int -> int = <fun> 
# fib 1;; 
- : int = 1 
# fib 2002;; 
- : int = 2002 

उत्तर

9

यह भ्रम का एक आम स्रोत है। संक्षेप में आप पैटर्न के बारे में सोचना चाहते हैं जैसे कि स्थिरांक (0 और 1) और पहचानकर्ता जो पैटर्न से पहचानते हैं।

जब कोई पहचानकर्ता पैटर्न में दिखाई देता है, तो यह किसी भी चीज़ से मेल खाता है, और पहचानकर्ता को मिलान किए गए मान को बांधता है। पैटर्न में एक पहचानकर्ता पहचानकर्ता से जुड़े किसी भी पिछले मान को संदर्भित करता है। तो, वास्तव में, आपका पैटर्न हमेशा पहले मामले से मेल खाता है और zero को i के मान से जोड़ता है।

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

+1

का एक परिणाम देता है बातें लिख सकते हैं द्वारा नजरअंदाज कर दिया जाता है, तो आप कुछ ऐसा करें जो x x = x zero' (सटीक वाक्यविन्यास मुझे बचता है) – hugomg

+2

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

+0

धन्यवाद तुम जेफरी, मुझे यह सुंदर मिला व्यावहारिक। –

0

मैंने सोचा कि मैं जोड़ना होगा कि है कि यदि आप इस प्रकार के लिए कोड दुबारा लिखा, कि यह ठीक काम करेगा:

# let zero = 0;; 
# let one = 1;; 
# let rec fib i = 
match i with 
    0 -> zero 
| 1 -> one 
| j -> fib (j - 2) + fib (j - 1);; 

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

let x = 1;; 
let x = 2 in let x = 3 in x;; 

जो आप स्थिरांक उपयोग कर सकते हैं 3.

+0

यह एक अच्छा मुद्दा है; पैटर्न में 'शून्य' की उपस्थिति एक नेस्टेड स्कोप बनाता है जहां मिलान के आधार पर 'शून्य' एक नए मान से जुड़ा हुआ है। अधिकांश प्रोग्रामिंग भाषाएं नेस्टेड स्कॉप्स का समर्थन करती हैं, न केवल ओकैमल। विकल्प आम तौर पर बदतर होते हैं; आप शायद कोड में कहीं और इस्तेमाल किए गए नामों के आधार पर स्थानीय नामों के विकल्पों को सीमित नहीं करना चाहते हैं। –

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