2012-07-16 11 views
10

मैं Put मोनैड का उपयोग कर Data.Binary पर सीधे उपयोग करने के लिए उलझन में हूं। मैंने Binary Generation बाइनरी डेटा से निपटने के अनुभाग को पढ़ा है, और ऐसा लगता है कि आपको Put का उपयोग करना चाहिए, लेकिन यह बहुत छोटा है क्यों नहीं समझाता है।हास्केल में बाइटस्ट्रिंग्स: क्या मुझे पुट या बिल्डर का उपयोग करना चाहिए?

Data.Binary.Put

रखें इकाई। आलसी bytestrings कुशलतापूर्वक निर्माण के लिए एक मोनड।

type Put = PutM() 

बिल्डर को केवल एक राइटर मोनाड में लिफ्ट करें, जो() पर लागू होता है।

Data.Binary.Builder

आलसी बाइट तार के कुशल निर्माण।


एक Writer इकाई की बात () के लिए आवेदन किया क्या है?

मैं देख सकता हूँ कि Put (एक विशेष प्रकार के पर्याय) जबकि Builder एक इकाई नहीं है, लेकिन मैं वास्तव में नहीं मिलता है क्यों Put जरूरत होगी।

मेरे मामले में, मैं एक 3 डी दृश्य प्रस्तुत कर रहा हूं और प्रत्येक पिक्सेल को 3 बाइट्स के रूप में लिख रहा हूं, और फिर शुरुआत में पीपीएम प्रारूप के शीर्षलेख को जोड़ रहा हूं (बाद में पीएनजी का उपयोग करूंगा)।

Binary ऐसा लगता है कि यह उन प्रकारों के लिए तत्काल होना है जिन्हें बाइनरी डेटा से क्रमबद्ध और deserialized किया जा सकता है। यह ठीक है कि मैं क्या कर रहा हूँ नहीं है, लेकिन यह मेरे रंग प्रकार के लिए Binary का दृष्टांत के लिए प्राकृतिक महसूस किया

instance (Binary a) => Binary (Colour a) where 
    put (Colour r g b) = put r >> put g >> put b 
    get = Colour <$> get <*> get <*> get 

यह put करने के लिए आसान एक 24 बिट में Colour Word8 बनाता है। लेकिन फिर मुझे हेडर पर भी निपटना होगा, और मुझे यकीन नहीं है कि मुझे यह कैसे करना चाहिए।

Builder दृश्यों के पीछे छिपा हुआ था, या यह निर्भर करता है? Binary कक्षा केवल (डी) डेटा क्रमबद्ध करने के लिए, या सभी द्विआधारी उत्पादन उद्देश्यों के लिए है?

+0

कोई जवाब नहीं है, लेकिन आप बाइनरी के बजाय ब्लेज़-बिल्डर (और दोस्तों) का उपयोग करने के लिए एक नज़र रखना चाहते हैं। –

+0

@ टिलोविकलंड: मैंने पहले देखा था। इसके बारे में क्या अलग है? क्या यह अधिक कुशल है? – mk12

+0

अन्य चीजों के अलावा। यहां लेखकों में से एक द्वारा एक अच्छा लेखन है: http://lambda-view.blogspot.se/2010/11/blaze-builder-library-faster.html –

उत्तर

10

सबसे पहले वैचारिक अंतर ध्यान दें। बिल्डर्स बाइटस्ट्रिंग स्ट्रीम की कुशल इमारत के लिए हैं, जबकि PutM मोनड वास्तव में क्रमबद्धता के लिए है। तो पहला सवाल आपको खुद से पूछना चाहिए कि क्या आप वास्तव में धारावाहिक कर रहे हैं (जवाब देने के लिए कि खुद से पूछें कि क्या एक सार्थक और सटीक विपरीत ऑपरेशन है - deserialization)।

सामान्य रूप से मैं इसे प्रदान करने के लिए Builder के साथ जाऊंगा। हालांकि, बाइनरी पैकेज से Builder पर नहीं, बल्कि वास्तव में ब्लेज़-बिल्डर पैकेज से। यह एक monoid है और कई पूर्वनिर्धारित स्ट्रिंग जेनरेटर है। यह भी बहुत संगत है। अंत में यह बहुत तेज़ है और वास्तव में ठीक-ठीक हो सकता है।

अंतिम लेकिन कम से कम तुम सच में गति, सुविधा और सुरुचिपूर्ण कोड आपके आस-पास नाली, प्रगणक या पाइप जैसे विभिन्न धारा प्रोसेसर पुस्तकालयों में से एक के साथ इस गठबंधन करना चाहते हैं चाहते हैं, तो नहीं।

9

मैं देख सकता हूँ कि Put एक इकाई है, जबकि Builder नहीं है, लेकिन मैं वास्तव में नहीं मिलता है क्यों Put जरूरत होगी।

सटीक होने के लिए, PutMMonad है। सुविधा के लिए इसकी आवश्यकता है, और आपको त्रुटियों के लिए कम अवसर प्रदान करने के लिए। मोनैडिक या आवेदक शैली में कोड लिखना अक्सर सभी अस्थायी क्षेत्रों को ले जाने से कहीं अधिक सुविधाजनक होता है, और Monad उदाहरण में किए गए नलसाजी के साथ, आप गलती से अपने फ़ंक्शन के बीच में गलत Builder का उपयोग नहीं कर सकते हैं।

आप PutM के साथ केवल Builder का उपयोग करके सब कुछ कर सकते हैं, लेकिन आमतौर पर यह कोड लिखने के लिए और अधिक काम है।

लेकिन फिर मुझे हेडर पर भी निपटना होगा, और मुझे यकीन नहीं है कि मुझे यह कैसे करना चाहिए।

मुझे पीपीएम प्रारूप नहीं पता है, इसलिए मुझे नहीं पता कि शीर्षलेख कैसे बनाया जाए। लेकिन इसे बनाने के बाद, आप इसे आसानी से putByteString या putLazyByteString का उपयोग कर सकते हैं।

+0

क्या आप इस बात से सहमत होंगे कि 'पुट' केवल धारावाहिक और deserializing के लिए है, और (उदाहरण के लिए) एक बाइनरी छवि (एक बाइटस्ट्रिंग के रूप में) डेटा को एक-तरफा प्रस्तुत करने के लिए केवल 'बिल्डर' (संभवतः ब्लेज़-बिल्डर) का उपयोग करके बेहतर किया जाएगा। , जैसा कि दूसरों ने कहा है? – mk12

+0

मैं कहूंगा कि 'put' और' get' हैं, लेकिन 'Put' और' Get' का व्यापक रूप से व्यापक दायरे के साथ उपयोग किया जा सकता है। हालांकि, [बाइनरी] का प्राथमिक इरादा (http://hackage.haskell.org/package/binary) वास्तव में (डी) हास्केल संरचनाओं का क्रमिकरण था, इसलिए इसके लिए इंटरफ़ेस आकार दिया गया था। इस प्रकार ब्लेज़-बिल्डर बेहतर विकल्प हो सकता है (मैंने इसका कभी भी उपयोग नहीं किया है, इसलिए मुझे नहीं पता कि इसका उपयोग करना कितना सुविधाजनक है)। –

3

मुझे यकीन है कि नहीं कर रहा हूँ करने के लिए किस हद तक यह सही है, लेकिन मेरी समझ हमेशा रहा है कि Put की प्रस्तुति आप इसे देख के रूप में काफी हद तक do-अंकन का दुरुपयोग होता है ताकि आप इस तरह कोड लिख सकते हैं:

putThing :: Thing -> Put 
putThing (Thing thing1 thing2) = do 
    putThing1 thing1 
    putThing2 thing2 

हम Monad (विशेष रूप से, हम किसी भी चीज़ के परिणाम को कभी भी बाध्य नहीं करते हैं) के "सार" का उपयोग नहीं कर रहे हैं, लेकिन हम concatenation के लिए एक सुविधाजनक और साफ वाक्यविन्यास प्राप्त करते हैं। हालांकि, पूरी तरह से monoidal विकल्प पर सौंदर्य लाभ:

putThing :: Thing -> Builder 
putThing (Thing thing1 thing2) = mconcat [ 
    putThing thing1, 
    putThing thing2] 

मेरे विचार में काफी कम है।

(ध्यान दें कि Get, इसके विपरीत, वास्तव में एक मोनाड और स्पष्ट तरीके से होने से लाभ)।

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

  • कोई संबंधित समस्या नहीं^_^