2012-01-16 18 views
8

मैं हमेशा जब एक ByteString पढ़ने का प्रयास निम्न त्रुटि प्राप्त:बाइटस्ट्रिंग को एक इंट में बदलने का सबसे अच्छा तरीका क्या है?

factSplice :: SnapletSplice App App 
factSplice = do 
    mbstr <- getParam "input" -- returns user input as bytestring 
    let str = maybe (error "splice") show mbstr 
    let n = read str :: Int 
    return [X.TextNode $ T.pack $ show $ product [1..n]] 

या शायद:
Prelude.read: no parse

यहाँ कोड का एक नमूना है कि एक ब्राउज़र में प्रतिपादन करते समय यह त्रुटि होने की कारण होगा है अधिक बस:

simple bs = read (show bs) :: Int 

किसी कारण से, show bs के बाद जिसके परिणामस्वरूप स्ट्रिंग, कोट भी शामिल है। इसलिए त्रुटि के चारों ओर जाने के लिए मुझे उद्धरण को read हटा देना होगा। मैं निम्नलिखित समारोह इंटरनेट से नकल ऐसा करने के लिए उपयोग करें:

sq :: String -> String 
sq [email protected][c]      = s 
sq ('"':s) | last s == '"' = init s 
      | otherwise  = s 
sq ('\'':s) | last s == '\'' = init s 
      | otherwise  = s 
sq s       = s 

फिर simple bs = read (sq.show bs) :: Int काम करता है के रूप में उम्मीद।

  1. यह मामला क्यों है?
  2. बाइटस्ट्रिंग को इंट में बदलने का सबसे अच्छा तरीका क्या है?

उत्तर

9

Show कुछ की एक String प्रतिनिधित्व बनाने के लिए प्रयोग किया जाता है, कि डिबगिंग और सादे-पाठ क्रमबद्धता लिए उपयोगी है। Show टाइपक्लास कुछ भी String में परिवर्तित करने का एक शानदार तरीका नहीं है। यही कारण है कि ByteString स्ट्रिंग में उद्धरण जोड़ता है: क्योंकि डेटा स्ट्रीम को डिबगिंग या deserializing जब इसे पढ़ने के लिए तर्कसंगत रूप से आसान है।

आप एक ByteString एक String कन्वर्ट करने के लिए Data.ByteString.Char8.unpack समारोह का उपयोग कर सकते हैं, लेकिन ध्यान दें कि इस unpacks ByteString बाइट-प्रति-बाइट, जो उच्च मूल्य यूनिकोड वर्ण या अन्य अक्षर हैं जो एक से अधिक बाइट के रूप में जमा हो जाती है को खराब करता ; यदि आप परिणाम पर read का उपयोग करने के अलावा कुछ और करना चाहते हैं, तो मैं ByteString को Text में बदलने की अनुशंसा करता हूं, जो इस स्थिति में अधिक लचीलापन प्रदान करता है। यह मानते हुए कि इस मामले में आपका एन्कोडिंग यूटीएफ 8 है (जैसा कि स्नैप में डिफ़ॉल्ट होना चाहिए), आप इसके लिए Data.Text.Encoding.decodeUtf8 फ़ंक्शन का उपयोग कर सकते हैं। फिर Text मान को String पर सही यूनिकोड प्रतीकों के साथ कनवर्ट करने के लिए, आप Data.Text.unpack का उपयोग करते हैं।

एक बार आपके पास String है, तो आप जितनी चाहें read पर निःशुल्क हैं; वैकल्पिक रूप से, आप Data.Text.Read मॉड्यूल में फ़ंक्शंस का उपयोग करके सीधे Text मान पढ़ना चुन सकते हैं।

+0

मेरे लिए प्रश्न # 2 अभी भी स्पष्ट नहीं है - या यह केवल एक और विशिष्ट उपयोग मामला हो सकता है जिसके बारे में मैं उत्सुक हूं और मुझे लगता है कि इस प्रारंभिक प्रश्न से संबंधित है: क्या होगा अगर किसी प्रकार का " लंबाई क्षेत्र "जिसे लेंस 4 के बाइटस्ट्रिंग के रूप में पार्स किया गया है, जो वास्तव में एक इंट 32 का वर्णन करता है। क्या आपका प्रस्तावित कामकाज अभी भी मान्य है? एक अधिक आरामदायक समाधान के रूप में मैं एक पुस्तकालय की तलाश में था जो इस तरह के बाइटस्ट्रिंग ले सकता है और सही इंट वापस कर देगा। क्या कोई पुस्तकालय है जो इस उपयोग के मामले को संभाल सकता है? –

10

ByteString को X में कनवर्ट करने का सबसे अच्छा तरीका X पर निर्भर करता है। यदि आपके पास String से अच्छा रूपांतरण है, तो Data.BytString.Char8.unpack के माध्यम से जाना अच्छा हो सकता है, यदि यह ASCII ByteString है। यूटीएफ -8 एन्कोडेड ByteString एस के लिए, utf8-string पैकेज में रूपांतरण फ़ंक्शन toString शामिल है। कुछ विशिष्ट प्रकारों के लिए, जैसे शीर्षक में उल्लिखित Int, विशेष तेज़ रूपांतरण मौजूद हैं। उदाहरण के लिए Data.ByteString.Char8.readInt और readInteger

+1

उन लोगों के लिए जो इंटरनेट से आ रहे हैं: ** यह जवाब है यदि "सर्वश्रेष्ठ तरीका" का अर्थ आपके लिए "कुशल तरीका" है! ** – donatello