Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to convert a ByteString to an Int?

I always run into the following error when trying to read a ByteString:
Prelude.read: no parse

Here's a sample of code that will cause this error to occur upon rendering in a browser:

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]]

Or perhaps more simply:

simple bs = read (show bs) :: Int

For some reason, after show bs the resulting string includes quotes. So in order to get around the error I have to remove the quotes then read it. I use the following function copied from the internet to do so:

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

Then simple bs = read (sq.show bs) :: Int works as expected.

  1. Why is this the case?
  2. What is the best way to convert a ByteString to an Int?
like image 664
qubital Avatar asked Jan 16 '12 23:01

qubital


People also ask

How do you convert a string to an int in Python?

To convert, or cast, a string to an integer in Python, you use the int() built-in function. The function takes in as a parameter the initial string you want to convert, and returns the integer equivalent of the value you passed. The general syntax looks something like this: int("str") .

Can we convert byte to int in Java?

The intValue() method of Byte class is a built in method in Java which is used to return the value of this Byte object as int.

How do you convert Bytearray?

Convert byte[] to String (text data) toString() to get the string from the bytes; The bytes. toString() only returns the address of the object in memory, NOT converting byte[] to a string ! The correct way to convert byte[] to string is new String(bytes, StandardCharsets. UTF_8) .

How do you convert Bytearray to long?

The BigInteger class has a longValue() method to convert a byte array to a long value: long value = new BigInteger(bytes). longValue(); Java.


2 Answers

Show is used to create a String representation of something, that is useful for debugging and plain-text serialization. The Show typeclass is not just a fancy way of converting anything into a String. That's why ByteString adds quotes to the string: because it's arguably easier to read it that way when debugging or deserializing a data stream.

You can use the Data.ByteString.Char8.unpack function to convert a ByteString to a String, but note that this unpacks the ByteString byte-per-byte, which messes up high-value Unicode characters or other characters that are stored as more than one byte; if you want to do something other than using read on the result, I'd recommend converting the ByteString to Text instead, which offers more flexibility in this situation. Assuming that your encoding is UTF8 in this case (As should be the default in Snap), you can use the Data.Text.Encoding.decodeUtf8 function for this. To then convert a Text value to a String with correct Unicode symbols, you use Data.Text.unpack.

Once you have a String, you are free to read it as much as you want; alternatively, you can choose to read a Text value directly using the functions in the Data.Text.Read module.

like image 123
dflemstr Avatar answered Oct 12 '22 09:10

dflemstr


What the best way to convert a ByteString to an X is depends onX. If you have a good conversion from String, going via Data.BytString.Char8.unpack can be good, if it's an ASCII ByteString. For UTF-8 encoded ByteStrings, the utf8-string package contains the conversion function toString. For some specific types, like Int, as mentioned in the title, special faster conversions exist. For example Data.ByteString.Char8.readInt and readInteger.

like image 35
Daniel Fischer Avatar answered Oct 12 '22 09:10

Daniel Fischer