में जटिल स्थिति को बनाए रखना मान लीजिए कि आप हास्केल में काफी बड़े सिमुलेशन का निर्माण कर रहे हैं। कई अलग-अलग प्रकार की संस्थाएं हैं जिनके गुण सिमुलेशन के रूप में अपडेट होते हैं। आइए, उदाहरण के लिए, कि आपकी संस्थाओं को बंदर, हाथी, भालू, आदि कहा जाता है ..हास्केल
इन संस्थाओं के राज्यों को बनाए रखने के लिए आपकी पसंदीदा विधि क्या है?
पहली और सबसे स्पष्ट दृष्टिकोण मैं के बारे में सोचा था इस:
mainLoop :: [Monkey] -> [Elephant] -> [Bear] -> String
mainLoop monkeys elephants bears =
let monkeys' = updateMonkeys monkeys
elephants' = updateElephants elephants
bears' = updateBears bears
in
if shouldExit monkeys elephants bears then "Done" else
mainLoop monkeys' elephants' bears'
यह पहले से ही बदसूरत इकाई के प्रत्येक प्रकार के स्पष्ट रूप से mainLoop
समारोह हस्ताक्षर में उल्लेख होने है। अगर आप 20 प्रकार की इकाइयां कहें तो आप कल्पना कर सकते हैं कि यह बिल्कुल भयानक कैसे होगा। (20 जटिल सिमुलेशन के लिए अनुचित नहीं है।) तो मुझे लगता है कि यह एक अस्वीकार्य दृष्टिकोण है। लेकिन इसकी बचत कृपा यह है कि updateMonkeys
जैसे कार्यों में वे बहुत स्पष्ट हैं: वे बंदरों की एक सूची लेते हैं और एक नया लौटते हैं।
तो फिर अगले सोचा एक बड़ा डेटा संरचना है कि सभी राज्य धारण में सब कुछ रोल होगा, इस प्रकार mainLoop
के हस्ताक्षर की सफाई:
mainLoop :: GameState -> String
mainLoop gs0 =
let gs1 = updateMonkeys gs0
gs2 = updateElephants gs1
gs3 = updateBears gs2
in
if shouldExit gs0 then "Done" else
mainLoop gs3
कुछ सुझाव है कि हम GameState
एक राज्य में लपेट do
में मोनाड और updateMonkeys
आदि पर कॉल करें। कोई बात नहीं। कुछ सुझाव देंगे कि हम इसे फ़ंक्शन संरचना के साथ साफ़ करें। ठीक है, मुझे लगता है। (बीटीडब्लू, मैं हास्केल के साथ एक नौसिखिया हूं, इसलिए शायद मैं इनमें से कुछ के बारे में गलत हूं।)
लेकिन फिर समस्या यह है कि updateMonkeys
जैसे कार्य आपको उनके प्रकार के हस्ताक्षर से उपयोगी जानकारी नहीं देते हैं। आप वास्तव में यह सुनिश्चित नहीं कर सकते कि वे क्या करते हैं। निश्चित रूप से, updateMonkeys
एक वर्णनात्मक नाम है, लेकिन यह थोड़ा सांत्वना है। जब मैं god object में पास करता हूं और कहता हूं "कृपया मेरी वैश्विक स्थिति अपडेट करें," मुझे लगता है कि हम अनिवार्य दुनिया में वापस आ गए हैं। यह किसी अन्य नाम से वैश्विक चर की तरह लगता है: आपके पास एक ऐसा कार्य है जो वैश्विक स्थिति में कुछ करता है, आप इसे कॉल करते हैं, और आप सबसे अच्छे उम्मीद करते हैं। (मुझे लगता है कि आप अभी भी कुछ समवर्ती समस्याओं से बचें जो एक अनिवार्य कार्यक्रम में वैश्विक चर के साथ मौजूद होंगे। लेकिन मेह, समेकन वैश्विक चर के साथ लगभग एकमात्र चीज गलत नहीं है।)
एक और समस्या यह है: मान लीजिए वस्तुओं को बातचीत करने की जरूरत है। क्योंकि निश्चित ही हम इसे यदि हाथियों के किसी भी किसी भी बंदरों की stomping श्रेणी में हैं देखने के लिए जाँच
stomp :: Elephant -> Monkey -> (Elephant, Monkey)
stomp elephant monkey =
(elongateEvilGrin elephant, decrementHealth monkey)
इस updateElephants
में कहा जाता हो जाता है कहते हैं: उदाहरण के लिए, हम इस तरह एक समारोह है। आप इस परिदृश्य में बंदरों और हाथियों दोनों में परिवर्तनों का सुंदर प्रचार कैसे करते हैं? हमारे दूसरे उदाहरण में, updateElephants
लेता है और एक ईश्वर वस्तु देता है, इसलिए यह दोनों परिवर्तनों को प्रभावित कर सकता है। लेकिन यह सिर्फ पानी को आगे बढ़ाता है और मेरे बिंदु को मजबूत करता है: भगवान वस्तु के साथ, आप प्रभावी रूप से वैश्विक चर को बदल रहे हैं। और यदि आप ईश्वर वस्तु का उपयोग नहीं कर रहे हैं, तो मुझे यकीन नहीं है कि आप उन प्रकार के परिवर्तनों का प्रचार कैसे करेंगे।
क्या करना है? निश्चित रूप से कई कार्यक्रमों को जटिल स्थिति का प्रबंधन करने की आवश्यकता है, इसलिए मुझे लगता है कि इस समस्या के कुछ प्रसिद्ध दृष्टिकोण हैं।
बस तुलना के लिए, यहां ओओपी दुनिया में समस्या का समाधान कैसे हो सकता है। Monkey
, Elephant
, आदि ऑब्जेक्ट्स होंगे। मेरे पास शायद सभी जीवित जानवरों के सेट में लुकअप करने के लिए क्लास विधियां होंगी। हो सकता है कि आप आईडी द्वारा, जो भी हो, स्थान से देख सकें।लुकअप फ़ंक्शंस के अंतर्गत डेटा संरचनाओं के लिए धन्यवाद, वे ढेर पर आवंटित रहेंगे। (मैं जीसी या संदर्भ गिनती मान रहा हूं।) उनके सदस्य चर हर समय उत्परिवर्तित हो जाएंगे। किसी भी वर्ग की कोई भी विधि किसी भी अन्य वर्ग के किसी भी जीवित प्राणी को बदलने में सक्षम होगी। जैसे एक Elephant
एक stomp
विधि है कि एक से पारित कर दिया-इन Monkey
वस्तु के स्वास्थ्य घटती हैं हो सकता था, और कहा कि
इसी तरह पारित करने के लिए, एक Erlang या अन्य अभिनेता उन्मुख डिजाइन में, आप इन समस्याओं को हल कर सकता है की कोई जरूरत नहीं होगी काफी सुंदरता: प्रत्येक अभिनेता अपने स्वयं के पाश और इस प्रकार अपने राज्य को बनाए रखता है, इसलिए आपको कभी भगवान की वस्तु की आवश्यकता नहीं होती है। और संदेश पास करने से ऑब्जेक्ट की गतिविधियों को कॉल स्टैक का बैक अप लेने के लिए सामानों का एक समूह गुजरने के बिना अन्य ऑब्जेक्ट्स में बदलावों को ट्रिगर करने की अनुमति मिलती है। फिर भी मैंने यह सुना है कि हास्केल में अभिनेता फंसे हुए हैं।
आप कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग – luqui
लिए देख रहे हैं [_Purely कार्यात्मक, घोषणात्मक खेल तर्क रिएक्टिव Programming_ का उपयोग करना] (https://github.com/leonidas/codeblog /blob/master/2012/2012-01-17-declarative-game-logic-afrp.md) आपको सही दिशा में इंगित कर सकता है। –
आप अभी भी बता सकते हैं कि 'अपडेटमॉकीज' क्या करता है, क्योंकि यह ':: राज्य -> बंदर -> राज्य' –