कॉम्बिनेटर क्या हैं और उन्हें प्रोग्रामिंग परियोजनाओं पर कैसे लागू किया जाता है? (व्यावहारिक स्पष्टीकरण)


51

कॉम्बिनेटर क्या हैं?

मैं देख रहा हूँ:

  • एक व्यावहारिक व्याख्या
  • वे कैसे उपयोग किए जाते हैं इसके उदाहरण
  • कॉम्बिनेटर कोड की गुणवत्ता / सामान्यता में सुधार कैसे करते हैं इसके उदाहरण

मैं नहीं ढूंढ रहा हूं:

  • कॉम्बिनेटरों के स्पष्टीकरण जो मुझे काम करने में मदद नहीं करते हैं (जैसे कि वाई-कॉम्बिनेटर)

संयोजक "क्रियाविशेषण" के समान हैं, फ़ंक्शंस जो फ़ंक्शंस में लेते हैं फिर अन्य फ़ंक्शंस लौटाते हैं। वे कोड के दोहराव को हटाने में मदद कर सकते हैं क्योंकि आपको चर के बीच की आवश्यकता नहीं है। कुछ उपयोगी दो बार हैं (f) = \ x -> f (f (x)), फ्लिप (op) -> \ xy -> y op x, (।) As (fg) x = f (g (x) के रूप में। )), ($) मानचित्र के साथ मदद कर सकता है (इन्टिक्स में <$> कहा जाता है) ($ ५) में <$> [(१/१), (* २)] = [६, १०], करी का उपयोग लिस्प में किया जा सकता है आंशिक अनुप्रयोग के लिए / पायथन / जावास्क्रिप्ट, और हेस्केल में रिकॉर्ड्स (टुपल्स) की आवश्यकता वाले कार्यों के लिए बिना उपयोग किए जा सकते हैं। जब x |> f = fa, x |> (लंबाई और&& योग) |> बिना खतना (/) औसत है।
aoeu256

जवाबों:


51

एक व्यावहारिक दृष्टिकोण से कॉम्बिनेटर एक तरह के प्रोग्रामिंग निर्माण हैं जो आपको दिलचस्प और अक्सर उन्नत शिष्टाचार में तर्क के टुकड़ों को एक साथ रखने की अनुमति देते हैं। आमतौर पर उनका उपयोग करना वस्तुओं में निष्पादन योग्य कोड को पैक करने में सक्षम होने की संभावना पर निर्भर करता है, जिसे अक्सर (ऐतिहासिक कारणों के लिए) लंबा फ़ंक्शन या लैम्ब्डा एक्सप्रेशन कहा जाता है, लेकिन आपका माइलेज अलग-अलग हो सकता है।

(उपयोगी) कॉम्बीनेटर का एक सरल उदाहरण वह है जो मापदंडों के बिना दो लंबो कार्यों को लेता है, और एक नया बनाता है जो उन्हें क्रम में चलाता है। वास्तविक कॉम्बिनेटर जेनेरिक छद्मकोड में इस तरह दिखता है:

func in_sequence(first, second):
  lambda ():
    first()
    second()

महत्वपूर्ण बात यह है कि यह एक संयोजन बनाता है दूसरी पंक्ति पर अनाम फ़ंक्शन (लैम्ब्डा फ़ंक्शन) है; जब तुमने फोन किया

a = in_sequence(f, g)

परिणामी वस्तु a पहले f () और फिर g () चलाने का परिणाम नहीं है, लेकिन यह एक ऐसी वस्तु है जिसे आप बाद में f () और g () क्रम से निष्पादित करने के लिए कॉल कर सकते हैं:

a() // a is a callable object, i.e. a function without parameters

आप तब समान रूप से एक कॉम्बिनेटर रख सकते हैं जो समानांतर में दो कोड ब्लॉक चलाता है:

func in_parallel(first, second):
  lambda ():
    t1 = start_thread(first)
    t2 = start_thread(second)
    wait(t1)
    wait(t2)

और फिर,

a = in_parallel(f, g)
a()

अच्छी बात यह है कि 'in_parallel' और 'in_fterence' दोनों एक ही प्रकार / सिग्नेचर वाले कॉम्बिनेटर हैं, अर्थात ये दोनों दो पैरामीटर रहित फंक्शन ऑब्जेक्ट्स लेते हैं और एक नया लौटाते हैं। आप वास्तव में तब जैसी चीजें लिख सकते हैं

a = in_sequence(in_parallel(f, g), in_parallel(h, i))

और यह उम्मीद के मुताबिक काम करता है।

मूल रूप से इसलिए कॉम्बिनेटर आपको एक प्रक्रियात्मक और लचीले फैशन में अपने कार्यक्रम के नियंत्रण प्रवाह (अन्य चीजों के बीच) का निर्माण करने की अनुमति देते हैं। उदाहरण के लिए, यदि आप अपने प्रोग्राम में समानता को चलाने के लिए in_parallel (..) कॉम्बिनेटर का उपयोग करते हैं, तो आप उस से संबंधित डीबगिंग को in_parallel combinator के कार्यान्वयन से जोड़ सकते हैं। बाद में, यदि आपको संदेह है कि आपके कार्यक्रम में समानता-संबंधी बग है, तो आप वास्तव में in_parallel को फिर से लागू कर सकते हैं:

in_parallel(first, second):
  in_sequence(first, second)

और एक झटके के साथ, सभी समानांतर वर्गों को अनुक्रमिक लोगों में बदल दिया गया है!

सही इस्तेमाल होने पर कॉम्बिनेटर बहुत उपयोगी होते हैं।

हालांकि, वाई कॉम्बिनेटर को वास्तविक जीवन में ज़रूरत नहीं है। यह एक कॉम्बीनेटर है जो आपको स्व-पुनरावर्ती कार्यों को बनाने की अनुमति देता है, और आप उन्हें वाई कॉम्बिनेटर के बिना किसी भी आधुनिक भाषा में आसानी से बना सकते हैं।


9

ब्रांड Y- कॉम्बीनेटर को कुछ कहना गलत है, जो "काम पूरा करने में मदद नहीं करेगा"। मैंने इसे कई अवसरों में बहुत उपयोगी पाया है। सबसे स्पष्ट मामला तब होता है जब आपको कुछ एम्बेडेड व्याख्या की गई भाषा को जल्दी से बूटस्ट्रैप करना होता है। आप पुरातन का एक न्यूनतम सेट प्रदान करते हैं, अर्थात् sequence, select, call, constऔर एक closure allocationहै, यह एक पूर्ण, मनमाने ढंग से जटिल भाषा के निर्माण के लिए पहले से ही पर्याप्त है। पुनरावृत्ति के लिए कोई विशेष समर्थन की आवश्यकता नहीं है - इसे एक निश्चित बिंदु कॉम्बिनेटर के माध्यम से जोड़ा जा सकता है। अन्यथा आपको बहुत अधिक जटिल प्राथमिकताओं की आवश्यकता होगी।

कॉम्बीनेटरों के लिए एक और स्पष्ट मामला मोटापा है। SKI पथरी में अनुवादित एक कोड व्यावहारिक रूप से अपठनीय है। यदि आपको वास्तव में एक एल्गोरिथ्म के कार्यान्वयन में बाधा डालना है, तो कॉम्बिनेटर का उपयोग करने पर विचार करें , यहां एक उदाहरण है

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

यह एक मजाक है , लेकिन बहुत ही सावधानीपूर्वक पढ़ने लायक एक मजाक है, क्योंकि कई आर्कन प्रोग्रामिंग तकनीकों और सिद्धांतों को वहां कवर किया गया है।


1
@MattFenwick, एक साधारण एम्बेडेड दुभाषिया में छोड़ने की आवश्यकता अक्सर उठती है जहां आप कभी भी इसकी उम्मीद नहीं करेंगे। उदाहरण के लिए, मेरे मामले में यह एक भाषा थी जिसे मुझे एक संचार प्रोटोकॉल का विस्तार करने के लिए डिजाइन करना था। सरल IPC पर्याप्त नहीं था, इसलिए प्रोटोकॉल को निष्पादन योग्य बनाना पड़ा।
एसके-तर्क

@MattFenwick, आपके प्रश्न के लिए: आप एपीएल या जे। कॉम्बिनेटर में कुछ कोड लिखने की कोशिश कर सकते हैं, इसलिए वहां आवश्यक हैं, इसलिए आपको इस बात का अंदाजा होगा कि उन्हें ठीक से कैसे लागू किया जाए। इसके अलावा, बिंदु-मुक्त शैली पर पढ़ने से मदद मिल सकती है: en.wikipedia.org/wiki/Tacit_programming
SK-logic

7

एक बिट के आसपास खुदाई, मुझे एक StackOverflow सवाल, "कॉम्बिनेटरों" (गैर गणितज्ञों के लिए) की अच्छी व्याख्या मिली जो इस प्रश्न का एक करीबी चचेरे भाई है। रेजिनाल्ड ब्रेथवेट के ब्लॉग होमोइकॉनिक को इंगित किए गए उत्तरों में से एक , जो कोड में कॉम्बीनेटर के कई उपयोगी उदाहरणों से जोड़ता है (उदाहरण के लिए केबी कॉम्बिनेटर , रूबी की Object#tapविधि द्वारा लागू किया गया - उदाहरण के लिए पेज पढ़ें कि यह क्यों उपयोगी है)।

Combinatory तर्क पर विकिपीडिया पृष्ठ अधिक विश्व स्तर पर combinators वर्णन करता है।


यह मेरे प्रश्न का दूसरा बुलेट पॉइंट है। उदाहरण के लिए धन्यवाद!

1
इस पोस्ट के कुछ अच्छे लिंक हैं लेकिन वास्तव में सीधे सवाल का जवाब नहीं देता है। उत्तर अपने दम पर पूरे होने चाहिए, और यदि आवश्यक हो तो संदर्भ के रूप में लिंक का उपयोग करें।
एरोन्यूज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.