2016-08-27 11 views
5

मैं जावास्क्रिप्ट में कार्यात्मक प्रोग्रामिंग से परिचित होने की कोशिश कर रहा हूं। मैं गया है बस read सूचक functor है कि:पॉइंट फिक्स्चर का सही उपयोग कैसे करें

एक of समारोह में किसी एक मूल्य डालता है के साथ एक वस्तु।

ES2015 Array.of एरे को एक पॉइंट इंजेक्टर बनाता है।

और मेरा प्रश्न यह है कि "एकल मूल्य" का क्या अर्थ है?

मैं एक फ़ैक्टर/कंटेनर (जैसे https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch8.html) बनाना चाहता हूं जिसमें दिए गए आयाम (चौड़ाई, ऊंचाई) के ग्रिड को 1-आयामी सरणी के रूप में रखा जाए और मुझे उस पर परिवर्तन करने की अनुमति मिलती है। एक सादा वस्तु के रूप में मैं इसे { width: 2, height: 2, list: [1, 2, 3, 4] } के रूप में संग्रहीत करता हूं लेकिन मैं इसे एक मजेदार में रखना चाहता हूं और मुझे यकीन नहीं है कि ठीक से कैसे करें।

मुझे पता है कि यह इस तरह उठाई functor उपयोग करने के लिए एकल मान स्टोर करने के लिए पूरी तरह से ठीक है:

Container.of(47) 

लेकिन यह मूल्य संभालने वस्तु के रूप में वस्तु का उपयोग करने के लिए ठीक है एक "एकल मूल्य" है:

Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] }) 

या यहां तक ​​कि इस तरह:

Grid.of(2, 2, [1, 2, 3, 4]) 
+0

'Foo.of' क्या है? क्या आपका मतलब Array.of? मैंने सोचा, एएस2015 के रूप में, केवल ऐरे और * टाइपेडअरे * में ' –

+0

था और आपका अपेक्षित आउटपुट क्या है? काफी तुम्हारा मुद्दा नहीं मिला। – Leo

+0

कृपया अपने इनपुट डेटा का एक उदाहरण दें, और अपेक्षित परिणामस्वरूप सरणी सामग्री - जैसा कि यह खड़ा है, आपने मुझे 'Foo' –

उत्तर

5

https://github.com/hemanth/functional-programming-jargon में स्पष्टीकरण दुर्भाग्य से बहुत सटीक नहीं है।

एक उठाई functor वास्तव में एक functor F एक समारोह ofहर प्रकारa के लिए परिभाषित है, और प्रकार F a के एक मूल्य of(x) में प्रकार a के एक मूल्य x भेजने के साथ एक साथ है। Hindley-Milner signature में यह इस तरह दिखता है:

of :: a -> F a 

उदाहरण के लिए, सरणी functor, of = x => [x] साथ दिखाया गया है किसी भी प्रकार a के हर मूल्य x के लिए परिभाषित किया।

इसके अलावा, समारोह of (या अधिक सटीक, कार्यों of के संग्रह के रूप में आप प्रत्येक प्रकार a के लिए एक है) पहचान functor से एक प्राकृतिक परिवर्तन F में होना चाहिए। इसका मतलब है कि एक समारोह के मूल्य के बराबर होती है of तर्क एक ही समारोह की मैप किया गया की of:

of(f(x)) === of(x).map(f) 

उदाहरण के लिए, सरणी उदाहरण में आप

[f(x)] === [x].map(f), 

तो x => [x] वास्तव में एक प्राकृतिक परिवर्तन है।

लेकिन क्या आप भी

of = x => [x, x] 
[f(x), f(x)] === [x, x].map(f) 

जो एक और उठाई functor है, भले ही functor के map ही रहता है ले जा सकते हैं। (ध्यान दें कि प्रत्येक मामले में, आपको केवल of(x) के मान के रूप में बहुत विशेष सरणी मिलती हैं।)

हालांकि, आप उदाहरण नहीं ले सकते

of = x => [x, 0] 
[f(x), 0] !== [x, 0].map(f) 

अब

var grid = Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] }) 

पूरी तरह से ठीक है और देता है अपने वस्तु Grid में लपेटा पारित। फिर आप अपने grid को सादे ऑब्जेक्ट्स से सादे ऑब्जेक्ट्स में किसी भी नियमित फ़ंक्शन f के साथ मैप कर सकते हैं और परिणाम प्राकृतिक परिवर्तन कानून के कारण f लागू करने और Grid में लपेटने जैसा ही होगा। ध्यान दें कि इस तरह आप Grid.of को Grid.of(2) के Grid.of({width: 2}) जैसे किसी भी अन्य मूल्य के साथ भी कॉल कर सकते हैं। वैकल्पिक रूप से, आप उन प्रकारों को प्रतिबंधित कर सकते हैं जिनके लिए Grid.of परिभाषित किया गया है, तो मान केवल उस प्रकार का होना चाहिए जो आप अनुमति देते हैं।


यह एक थोड़ा मुश्किल है:

Grid.of(2, 2, [1, 2, 3, 4]) 

यह कई तर्क पर लागू होता है Grid.of।चूंकि Grid.of परिभाषा के अनुसार केवल एक तर्क का कार्य है, परिणाम Grid.of(2) होगा, जो आप जो चाहते हैं वह हो सकता है। क्या तुम सच में सभी मूल्यों को खिलाने के लिए चाहते हैं, तो आप शायद आप आंतरिक एक सरणी में उन्हें पूर्व लपेटकर और उसके बाद Grid.of लगाने से कई तर्कों को Grid.of विस्तार कर सकते हैं

Grid.of([2, 2, [1, 2, 3, 4]]) 

वैकल्पिक रूप से लिखना चाहते हैं,। यह वास्तव में इस बात पर निर्भर करता है कि आप क्या कर रहे हैं।

वास्तविक दुनिया उपयोग उदाहरण के लिए, उदाहरण देखें here जहां एक "उबाऊ" कार्य को सादा मूल्य से Task.of के माध्यम से परिभाषित किया गया है। दूसरी तरफ here एक और दिलचस्प कार्य है जो एक फ़ंक्शन को लपेटता है जिसे आप Task.of के साथ नहीं प्राप्त करेंगे। हालांकि महत्वपूर्ण बात यह है कि दोनों उदाहरणों पर दिखाए गए अनुसार समान कार्य इंटरफ़ेस के साथ दोनों कार्य का उपयोग किया जा सकता है।

यह भी ध्यान दें कि इन उदाहरणों में कोई भी आवेदक फ़ैक्टर का उपयोग नहीं किया जाता है, इसलिए अभी भी आवेदक के बिना पॉइंट किए गए फ़ैक्टर का उपयोग किया जाता है।

4

लेकिन क्या ऑब्जेक्ट का उपयोग करना ठीक है क्योंकि मान मानते हुए ऑब्जेक्ट एक "सिंगल वैल्यू" है:

हां। ofकिसी भी मान लेना और इसे कंटेनर के अंदर रखना चाहिए। एक वस्तु निश्चित रूप से एक ही मूल्य है।

Grid.of(2, 2, [1, 2, 3, 4])

सं of एक एकल पैरामीटर लेने के लिए माना जाता है। यदि आप एक मज़ेदार के अंदर कई मान डालना चाहते हैं, तो उन्हें पहले एक अन्य संरचना के अंदर रखें और उस संरचना को मज़ेदार के अंदर रखें, या इसके बिंदु फ़ंक्शन (of) से कुछ और द्वारा मज़ेदार बनाएं।

Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })

नहीं, अगर आपको लगता है कि फिर इनपुट वापस जाने के लिए उम्मीद यह काम नहीं करेगा। of को इनपुट के रूप में इनपुट लेना चाहिए और इसके चारों ओर संरचना को लपेटना चाहिए। अपने ग्रिड के मामले में, यह सबसे निश्चित रूप से इस प्रकार दिखाई देगा:

// Grid<A> 
class Grid { 
    // Int -> Int -> [A] -> Grid<A> 
    constructor(w, h, vals) { 
     assert(Number.isInteger(w) && Number.isInteger(h)); 
     this.width = w; 
     this.height = h; 
     const list = Array.from(vals); 
     assert(list.length == w * h); 
     this.list = list; 
    } 
    // Grid<A> -> (A -> B) -> Grid<B> 
    map(f) { 
     return new Grid(this.width, this.height, this.list.map(f)); 
    } 
    // A -> Grid<A> 
    static of(x) { 
     return new Grid(1, 1, [x]); 
    } 
} 

तो ऊपर कॉल, वस्तुओं की एक Grid पैदा करेगा चार नंबर की नहीं एक ग्रिड। ध्यान दें कि of एक मजेदार का उदाहरण बनाने का एकमात्र तरीका नहीं है, यह केवल एक तत्व से एक उदाहरण बनाने का तरीका है।

ध्यान दें कि of आवेदक के हिस्से के रूप में सबसे महत्वपूर्ण है, सामान्य फंक्टरों के लिए इतना दिलचस्प नहीं है।बीटीडब्ल्यू, यदि आप कार्यात्मक प्रोग्रामिंग अवधारणाओं में रुचि रखते हैं, तो आपको Grid एक मोनॉयड, एक ट्रैवर्सबल और मोनाड बनाने में भी सक्षम होना चाहिए - https://github.com/fantasyland/fantasy-land देखें।

+0

तो ऐसा लगता है कि मुझे 'बिल्कुल' की आवश्यकता नहीं है और मुझे बस एक वस्तु बनाने का एक सभ्य तरीका है। मैं कक्षाओं से परहेज कर रहा था क्योंकि वे मेरे लिए गैर-कार्यात्मक प्रतीत होते हैं और मैंने उन्हें कभी भी किसी भी प्रकार के ट्यूटोरियल में नहीं देखा ... अब मुझे लगता है कि इन दोनों दुनिया को एक साथ जोड़ दिया जा सकता है। – jesper

+0

कन्स्ट्रक्टर शुद्ध कैसे बनाएं? मैं छवि हूं कि 'जोर' को ओओपी दुनिया में किसी तरह का अपवाद फेंकना चाहिए, लेकिन अगर मैं इसे पूरी तरह कार्यात्मक बनाना चाहता हूं तो क्या होगा? मैं या तो, बाएं और दाएं से परिचित हूं लेकिन मुझे यकीन नहीं है कि इसे यहां कैसे लागू किया जाए। मेरे पास एक समाधान है कि ग्रिड ऑब्जेक्ट को एक फ़ंक्शन में बनाने का प्रतिनिधि है जो जांचता है कि प्रदान किए गए मान मान्य ग्रिड निर्दिष्ट करते हैं और फिर _either_ को ग्रिड ऑब्जेक्ट या त्रुटि देता है। क्या यह एक सही दृष्टिकोण है? – jesper

+1

@ जेस्पर: हां, 'की' आवश्यकता नहीं है और उदाहरण बनाने के लिए एकमात्र तरीका नहीं है। आपको केवल इसकी आवश्यकता है यदि आप चाहते हैं कि आपका डेटा प्रकार फंतासी-भूमि विनिर्देश के अनुरूप हो, जो इसे रामडा जैसे कई कार्यात्मक पुस्तकालयों के साथ बॉक्स से बाहर कर देता है। और हां, 'वर्ग' किसी भी कार्यात्मक दृष्टिकोण से विरोधाभासी नहीं हैं - आपको डेटा रखने के लिए हमेशा "रिकॉर्ड" या "ऑब्जेक्ट्स" करने के लिए कुछ तरीका चाहिए। आप फैक्ट्री फ़ंक्शन और स्थिर फ़ंक्शंस के साथ ऐसा ही कर सकते हैं, मैंने यहां 'क्लास' सिंटैक्स को चुना है क्योंकि यह छोटा है। – Bergi

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