2012-06-10 7 views
10

परहेज मैं इन डेटा प्रकार है:हास्केल: "किस प्रकार के" कार्यों को प्राप्त करना चाहिए? और पूर्ण "पुनर्निर्माण"

data PointPlus = PointPlus 
    { coords :: Point 
    , velocity :: Vector 
    } deriving (Eq) 

data BodyGeo = BodyGeo 
    { pointPlus :: PointPlus 
    , size :: Point 
    } deriving (Eq) 

data Body = Body 
    { geo :: BodyGeo 
    , pict :: Color 
    } deriving (Eq) 

यह अक्षर, दुश्मन, वस्तुओं, आदि मेरी खेल में (अच्छी तरह से, मैं सिर्फ खिलाड़ी के रूप में दो आयतों है के लिए आधार डेटाप्रकार है और जमीन अभी अभी: पी)।

जब कोई कुंजी, वर्ण velocity बदलकर दाएं, बाएं या कूदता है। को coords पर जोड़कर स्थानांतरण किया जाता है।

move (PointPlus (x, y) (xi, yi)) = PointPlus (x + xi, y + yi) (xi, yi) 

मैं बस अपना Body और नहीं पूरे Body की PointPlus हिस्सा ले रहा हूँ, अन्यथा यह होगा::

move (Body (BodyGeo (PointPlus (x, y) (xi, yi)) wh) col) = (Body (BodyGeo (PointPlus (x + xi, y + yi) (xi, yi)) wh) col) 

move बेहतर का पहला संस्करण है वर्तमान में, यह इस प्रकार लिखा है ? वैसे भी, अगर move केवल PointPlus बदलता है, तो एक और फ़ंक्शन होना चाहिए जो इसे नए Body के अंदर कॉल करता है। मैं समझाता हूं: एक समारोह update है जिसे गेम स्थिति अपडेट करने के लिए कहा जाता है; यह वर्तमान खेल स्थिति, अब के लिए एक एकल Body पारित किया गया है, और अद्यतन Body देता है।

update (Body (BodyGeo (PointPlus xy (xi, yi)) wh) pict) = (Body (BodyGeo (move (PointPlus xy (xi, yi))) wh) pict) 

जो मुझे गुदगुदी करता है। PointPlus को छोड़कर सबकुछ Body के भीतर ही रखा जाता है। हाथ से इस पूर्ण "पुनर्निर्माण" से बचने का कोई तरीका है? इस तरह:

update body = backInBody $ move $ pointPlus body 

बेशक backInBody को परिभाषित किए बिना।

उत्तर

14

आप "लेंस" की तलाश में हैं। लेंस के लिए कई अलग-अलग पैकेज हैं; here उनमें से एक अच्छा सारांश है। b के मूल्य और b का एक अलग मूल्य के साथ एक नया a पाने के लिए एक तरह से प्राप्त करने के लिए एक तरह से:

मेरे समझ है कि कुछ क्षेत्र b के लिए एक डेटा प्रकार a पर एक लेंस दो आपरेशन प्रदान करता है। तो आप गहरे घोंसले PointPlus के साथ काम करने के लिए बस एक लेंस का उपयोग करेंगे।

लेंस पैकेज लेंस के साथ काम करने के साथ-साथ स्वचालित रूप से लेंस उत्पन्न करने के तरीके (टेम्पलेट हास्केल के साथ) के लिए उपयोगी कार्यों प्रदान करते हैं जो बहुत सुविधाजनक हो सकते हैं।

मुझे लगता है कि वे आपकी परियोजना के लिए देख रहे हैं, विशेष रूप से क्योंकि आपको अन्य स्थानों में घोंसले के साथ समान समस्याओं का सामना करना पड़ सकता है, जो आपके डेटा प्रकारों की संरचना के लिए धन्यवाद।

+0

यह सही है, खासकर स्वचालित पीढ़ी के साथ! 'चाल' फ़ंक्शन के बारे में क्या? क्या यह पूरी तरह से 'बॉडी' या केवल 'प्वाइंटप्लस' भाग लेने के लिए बेहतर है? – L01man

+3

@ एल 01man मैं लेंस पर खान के एक ब्लॉग पोस्ट में आपके जैसा ही एक ठोस उदाहरण का वर्णन करता हूं [यहां] (http://www.haskellforall.com/2012/01/haskell-for-mainstream-programmers_28.html) –

+0

आपके चरण-दर-चरण व्याख्या ने मुझे पूरी तरह से लेंस समझने में मदद की। – L01man

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