2011-12-21 17 views
25

मैंने अतीत में erlang का उपयोग किया है और इसमें पैटर्न मिलान कार्यों या "फ़ंक्शन गार्ड" जैसी कुछ वास्तव में उपयोगी चीजें हैं। erlang डॉक्स से उदाहरण है:क्लोजर में पैटर्न मिलान कार्य?

fact(N) when N>0 -> 
    N * fact(N-1); 
fact(0) ->  
    1.  

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

क्या क्लोजर में कुछ भी समान है?

+0

यह एक पुरानी सवाल है, लेकिन यह प्रोजेक्ट कोर.मैच को फ़ंक्शंस में फैलाता है और लगभग वही है जो मैं साल पहले पूछ रहा था https://github.com/killme2008/defun – mikkom

उत्तर

27

कोर.मैच (https://github.com/clojure/core.match) पुस्तकालय में एकीकरण के साथ ऐसा करने के लिए चल रहे काम चल रहे हैं।

आप जो करना चाहते हैं उसके आधार पर, एक और आम तरीका है मनमानी कार्यों पर प्रेषण के लिए defmulti/defmethod का उपयोग करना। देखें http://clojuredocs.org/clojure_core/clojure.core/defmulti (उस पृष्ठ के निचले हिस्से में फैक्टोरियल उदाहरण है)

+3

core.match लगभग उसी कोड जैसा है जिसे मैं कोड स्तर पर देख रहा हूं, क्या यह हिस्सा है 1.3 का मूल (मुझे बिल्कुल समझ में नहीं आता कि सी कैसे lojure पैकेजिंग काम करता है)? कुछ मैक्रोज़ के साथ मुझे लगता है कि कार्यों में वाक्यविन्यास का विस्तार करना संभव होगा (इरलांग में आईएमएचओ स्पष्ट कोड गार्ड के साथ पैटर्न मिलान कार्यों के साथ लिखा जा सकता है) – mikkom

+0

इसे 1.3 की आवश्यकता है लेकिन डिफ़ॉल्ट रूप से 1.3 का हिस्सा नहीं है। यदि आप लीनिंगेन (https://github.com/technomancy/leiningen) का उपयोग कर रहे हैं - और आपको होना चाहिए - तो आप एक पंक्ति '[org.clojure/core.match "0.2.0-alpha8"]' जोड़ते हैं आपकी project.clj की निर्भरता, फिर लीन डीपी चलाएं। और हां, जैसा कि आप अपने जीथब पेज के निचले भाग में देख सकते हैं, देवताओं को जल्द ही कार्यों (कोर प्रेषण) को कोर.मैच लागू करने की योजना है। – gilesc

+0

यदि कोई और परेशानी पैटर्न मिलान कार्य तर्कों में चलता है, तो 'vec' का उपयोग करें: http://nickknowlson.com/blog/2013/02/17/using-core-match-with-function-arguments/ –

9

core.match क्लोजर के लिए एक पूर्ण-विशेषीकृत और एक्स्टेंसिबल पैटर्न मिलान लाइब्रेरी है। एक छोटे मैक्रो जादू के साथ और आप जो भी खोज रहे हैं उसके लिए शायद आप एक बहुत करीब अनुमान लगा सकते हैं।

3

इसके अलावा, यदि आप वैक्टर और मानचित्र जैसे किसी भी साधारण संरचना को अलग करना चाहते हैं (कोई भी चीज जो अनुक्रम या मानचित्र है, उदाहरण के लिए रिकॉर्ड, वास्तव में), आप destructuring bind का भी उपयोग कर सकते हैं। यह पैटर्न मिलान का कमजोर रूप है, लेकिन अभी भी बहुत उपयोगी है। इसके बावजूद let अनुभाग में वर्णित है, इसका उपयोग फ़ंक्शन परिभाषाओं सहित कई संदर्भों में किया जा सकता है।

+2

विनाशकारी काफी है वास्तविक पैटर्न मिलान के लिए थोड़ा सीमित भी है। – mikkom

12

मैं defun पेश करना चाहता हूं, यह एरलैंग की तरह पैटर्न मिलान के साथ कार्यों को परिभाषित करने के लिए एक मैक्रो है, यह core.match पर आधारित है। इसके बाद के संस्करण तथ्य समारोह में लिखा जा सकता है:

(use 'defun) 
(defun fact 
    ([0] 1) 
    ([(n :guard #(> % 0))] 
    (* n (fact (dec n))))) 

एक अन्य उदाहरण है, सकारात्मक संख्या शून्य से एक संचायक n:

(defun accum 
    ([0 ret] ret) 
    ([n ret] (recur (dec n) (+ n ret))) 
    ([n] (recur n 0))) 

अधिक जानकारी कृपया देखें https://github.com/killme2008/defun

+1

यह सुंदर है! प्रोजेक्ट के साथ शुभकामनाएं मुझे यकीन है कि यह बहुत से लोगों की मदद करेगा क्योंकि पैटर्न मिलान करने वाले कार्यों प्रोग्रामिंग में सबसे कमजोर चीजों में से एक है। – mikkom

+0

@ killme2008, मुझे वास्तव में defun के साथ अपने काम पसंद है। Core.match पर defun के फायदे क्या हैं? –

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